Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Chapter 16 How to work with XML Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 1 Objectives Applied Use servlets to work with XML files whenever you need to do that. Knowledge Describe two common types of uses for XML files. Distinguish between storing data in an attribute and storing data as content for an element. In general terms, describe the use of a Document Type Definition. In general terms, describe the use of the API for the Document Object Model. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 2 Tabular data for three users First name Andrea Joel Alexandra Java Servlets and JSPCH16 Last name Steelman Murach White Email address [email protected] [email protected] [email protected] © 2003, Mike Murach & Associates, Inc. Contact no yes yes Slide 3 Data stored in an XML document <?xml version="1.0" encoding="UTF-8"?> <!--User Information--> <Users> <User contact="no"> <firstName>Andrea</firstName> <lastName>Steelman</lastName> <emailAddress>[email protected]</emailAddress> </User> <User contact="yes"> <firstName>Joel</firstName> <lastName>Murach</lastName> <emailAddress>[email protected]</emailAddress> </User> <User contact="yes"> <firstName>Alexandra</firstName> <lastName>White</lastName> <emailAddress>[email protected]</emailAddress> </User> </Users> Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 4 Common uses of XML Control files Files for exchanging data between two different systems Business data files that contain small amounts of data, especially if they are used by two different types of systems. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 5 An introduction to XML XML, which stands for Extensible Markup Language, is a method of structuring information. An XML document uses XML tags to identify the data elements. When an XML document is stored in an XML file, the file usually has an extension of XML. Unlike HTML tags, XML tags are case-sensitive. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 6 A User element and its child elements <?xml version="1.0" encoding="UTF-8" ?> User element <!--User information--> firstName <Users> element <User contact="no"> <firstName> Andrea</firstName> lastName <lastName>Steelman</lastName> element <emailAddress>[email protected]</emailAddress> emailAddress </User> element </Users> Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 7 A User element that adds another level of child elements <User contact="no"> <firstName>Andrea</firstName> <lastName>Steelman</lastName> <emailAddresses> <emailAddress>[email protected]</emailAddress> <emailAddress>[email protected]</emailAddress> </emailAddresses> </User> Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 8 XML declarations and comments The first line in an XML document is an XML declaration that indicates which version of the XML standard is being used for the document. The XML declaration usually identifies the standard character set that’s being used (UTF-8 is the character set that’s commonly used for XML documents in English-speaking countries). XML comments are coded the same way HTML comments are coded. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 9 XML elements An XML element begins with a starting tag and ends with an ending tag. The starting tag provides the name of the element and contains any attributes assigned to the element. The ending tag repeats the element name, but is prefixed with a slash (/). The content for an element is coded within the element’s starting and ending tags. An element can contain one or more other elements. An element that’s contained within another element is the child element. An element that contains a child element is a parent element. The highest-level parent element in an XML document is the root element. An XML document must have one and only one root element. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 10 An attribute of the User element <?xml version="1.0" encoding="UTF-8" ?> <!--User information--> the contact attribute <Users> <User contact="no" > <firstName> Andrea</firstname> <lastName>Steelman</lastname> <emailAddress>[email protected]</emailAddress> </User> </Users> Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 11 XML attributes You can include one or more XML attributes in the starting tag for an element. An attribute consists of an attribute name, an equals sign, and a string value in single or double quotes. Unlike HTML, the quotes around the attribute are required. If an element has more than one attribute, the attributes must be separated by one or more spaces. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 12 When to use attributes instead of child elements When you design an XML document, you can use child elements or attributes to identify the data items of an element. The choice of whether to implement a data item as an attribute or as a child element is often a matter of preference. Although attributes require less code, an element that contains too many attributes can become unwieldy. Although child elements require more code, they’re usually easier to read, they’re better for working with long string values, and they can store additional child elements. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 13 The rules for an XML document The document must contain one and only one Users element. The document can contain multiple User elements. Each of these User elements must contain three elements named firstName, lastName, and emailAddress. Each User element can contain one attribute named contact that can hold either a default “yes” value or a “no” value. The firstName, lastName, and emailAddress elements can contain any text data. They can’t contain child elements. A DTD the implements these rules <!DOCTYPE Users [ <!ELEMENT User (firstName, lastName, emailAddress)> <!ATTLIST User contact (yes|no) "yes"> <!ELEMENT firstName (#PCDATA)> <!ELEMENT lastName (#PCDATA)> <!ELEMENT emailAddress (#PCDATA)> ]> Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 14 How to refer to a DTD file in an XML document <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE Users SYSTEM "c:/tomcat/webapps/murach/web-inf/etc/users.dtd"> <!--User information--> <Users> <User contact="no"> <firstName>Andrea</firstName> <lastName>Steelman</lastName> <emailAddress>[email protected]</emailAddress> </User> </Users> Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 15 DTD declarations Keyword DOCTYPE ELEMENT ATTLIST Java Servlets and JSPCH16 Defines The root element The names of the child elements or the element name and the type of data it will contain The names of the attributes and the types of data they will contain © 2003, Mike Murach & Associates, Inc. Slide 16 An introduction to DTDs To define the conditions of an XML document, you use a schema language to create a schema. These conditions can then be enforced for any XML document that’s based on the schema. Document Type Definition, or DTD, is a schema language that’s part of standard XML. It is supported by SDK 1.4. XML Schema Definition, or XSD, is a newer schema language that’s part of standard XML. It is more flexible than DTD, but it is also more difficult to work with and it isn’t supported by SDK 1.4. An XML document can refer to a DTD that’s stored in a file or it can contain an inline DTD at the start of the XML document. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 17 SAX is Memory efficient Read-only Typically used for working with documents larger than 10 megabytes DOM is Memory intensive Read-write Typically used for working with documents smaller than 10 megabytes Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 18 An introduction to XML APIs Version 1.4 of the SDK includes two APIs that you can use to parse XML documents to get the data you want. Two types of APIs exist for processing XML documents with Java. The Simple API for XML (SAX) and the Document Object Model (DOM). SAX reads one line at a time and lets you access the tags in the line immediately. DOM reads an entire XML document before you can access the individual tags. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 19 The structure of the DOM tree Node A Document User Node B Element Users Node C Comment Node D Element User Node F Attr contact Java Servlets and JSPCH16 Node E Element User Node G Element firstName Node H Element lastName Node I Element emailAddress Node J Text Andrea Node K Text Steelman Node L Text [email protected] © 2003, Mike Murach & Associates, Inc. Slide 20 The DOM tree You can use the DOM API to load an XML document into a DOM tree. Then, you can use the DOM API to work with the data in the DOM tree. A DOM tree is a collection of nodes. Each node may have a parent node, one or more child nodes, and one or more sibling nodes. Each node has a node type that indicates whether the node represents the document, an element, a comment, an attribute, or a text value. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 21 The Node interface hierarchy Node Document Element CharacterData Text Java Servlets and JSPCH16 Attr Comment © 2003, Mike Murach & Associates, Inc. Slide 22 Interfaces for working with the DOM tree The Node interface represents a single node in the DOM tree. The Document, Element, Text, Comment, and Attr interfaces represent the different types of nodes available in a DOM tree. You can use the methods of these interfaces to work with the nodes of a DOM tree. Since the Document, Element, CharacterData, Attr, Text, and Comment interfaces inherit the Node interface, you can use any of the methods in the Node interface to work with nodes. These interfaces are located in the org.w3c.dom package. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 23 Code that creates an empty DOM tree DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); Packages javax.xml.parsers org.w3c.dom Exceptions javax.xml.parsers.ParserConfigurationException Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 24 Code that creates and appends the root element Element rootElement = doc.createElement("Users"); doc.appendChild(rootElement); Code that creates and appends a comment Comment comment = doc.createComment("User Information"); doc.appendChild(comment); Code that creates and appends an element Element userElement = doc.createElement("User"); rootElement.appendChild(userElement); Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 25 Code that sets an attribute userElement.setAttribute("contact", "yes"); Code that creates and appends an element that contains text Element firstNameElement = doc.createElement("firstName"); userElement.appendChild(firstNameElement); Text firstNameText = doc.createTextNode("firstName"); firstNameText.setNodeValue("Alexandra"); firstNameElement.appendChild(firstNameText); Packages org.w3c.dom Exceptions org.w3c.dom.DOMException Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 26 Code that writes a DOM tree to a file //Prepare the DOM document as the input source DOMSource in = new DOMSource(doc); //Prepare the output file File xmlFile = new File("C:/tomcat/webapps/murach/WEBINF/etc/users.xml"); StreamResult out = new StreamResult(xmlFile); // Write the DOM document to the file Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "4"); transformer.transform(in, out); Exception javax.xml.transform.TransformerException Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 27 How to write a DOM tree to a file To specify the DOM tree as the input source, you create a DOMSource object from the Document object. To specify an XML file as the output, you create a StreamResult object that points to an XML file. To write the DOM tree to the XML file, you create a Transformer object by calling the newTransformer method of the TransformerFactory class. Then, you can call the transform method of the Transformer object. If you don’t specify any output properties in the Transformer object, the XML document will appear as one continuous string and may be difficult to read. To specify indentation and other formatting, you can use the setOutputProperty methods. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 28 How to write a DOM tree to a file (continued) The DOMSource class is located in the javax.xml.transform.dom package, the StreamResult interface is located in the javax.xml.transform.stream package, and the Tranformer and TransformerFactory classes are located in the javax.xml.transform package. Both the newTransformer method of the TransformerFactory class and the transform method of the Transformer class throw a TransformerException. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 29 Code that reads a DOM tree from a file InputSource in = new InputSource( "c:/tomcat/webapps/murach/web-inf/etc/users.xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(in); Code that reads a DOM tree and validates it against its DTD schema InputSource in = new InputSource( "c:/tomcat/webapps/murach/web-inf/etc/users.xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(in); Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 30 Methods of the DocumentBuilderFactory class setIgnoringComments(boolean b) setIgnoringElementContentWhitespace(boolean b) setValidating(boolean b) Packages javax.xml.parsers org.w3c.dom Exceptions java.io.IOException org.xml.sax.SAXException Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 31 How to read a DOM tree from a file To get a Document object for an existing XML document, you can call the parse method of the DocumentBuilder object with an InputSource object that points to the XML file as its argument. By default, the three set methods above are set to false. If that’s not what you want, you can call them from the DocumentBuilder object and change them so they’re true. The parse method of the DocumentBuilder class throws a SAXException and an IOException. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 32 Code that reads the root element of the DOM tree Element root = doc.getDocumentElement(); Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 33 Code that reads all EmailAddress elements into a vector Vector emailVector = new Vector(); NodeList emailList = doc.getElementsByTagName("emailAddress"); for (int i = 0; i < emailList.getLength(); i++){ Element emailElement = (Element) emailList.item(i); Text emailText = (Text) emailElement.getFirstChild(); String emailAddress = emailText.getNodeValue(); emailVector.add(emailAddress); } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 34 Code that reads all User elements into a vector Vector users = new Vector(); NodeList usersList = doc.getElementsByTagName("User"); for (int i = 0; i < usersList.getLength(); i++){ Element userElement = (Element) usersList.item(i); String contact = userElement.getAttribute("contact"); NodeList firstList = userElement.getElementsByTagName("firstName"); Element firstElement = (Element) firstList.item(0); Text firstText = (Text) firstElement.getFirstChild(); String firstName = firstText.getNodeValue(); Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 35 The code (continued) NodeList lastList = userElement.getElementsByTagName("lastName"); Element lastElement = (Element) lastList.item(0); Text lastText = (Text) lastElement.getFirstChild(); String lastName = lastText.getNodeValue(); NodeList emailList = userElement.getElementsByTagName("emailAddress"); Element emailElement = (Element) emailList.item(0); Text emailText = (Text) emailElement.getFirstChild(); String emailAddress = emailText.getNodeValue(); User user = new User(firstName, lastName, emailAddress); users.add(user); } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 36 How to read the nodes of a DOM tree The NodeList interface stores a collection of Node objects. You can use the getLength and item methods to loop through the Node objects stored in a NodeList object. You can use the getElementsByTagName method to return a NodeList object that contains a collection of nodes for the specified tag. You can use the getDocumentElement method to return the root element of the XML document. You can use the getAttribute method to return the value of the specified attribute. You can use the getFirstChild method to return the first child node. You can use the getNodeValue method to return the value of a text node. Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 37 Code that appends an element after all other child nodes root.appendChild(userElement); Code that inserts an element before another child node root.insertBefore(userElement1, userElement2); Code that updates an element root.replaceChild(userElement1, userElement2); Code that removes an element root.removeChild(userElement); Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 38 Methods of the Node interface for adding, updating, and deleting elements appendChild(Node child) insertBefore(Node newChild, Node refChild) replaceChild(Node newChild, Node oldChild) removeChild(Node child) Exceptions org.w3c.dom.DOMException Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 39 The XMLUtil class package util; import import import import import import import org.xml.sax.*; org.w3c.dom.*; javax.xml.transform.*; javax.xml.transform.dom.*; javax.xml.transform.stream.*; javax.xml.parsers.*; java.io.*; public class XMLUtil{ public static Document getDocumentFromFile( String xmlFile) throws IOException, ParserConfigurationException, SAXException{ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputSource in = new InputSource(xmlFile); Document doc = db.parse(in); return doc; } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 40 The XMLUtil class (continued) public static String getTextNodeValue(Element parent, String tagName){ NodeList list = parent.getElementsByTagName(tagName); Element element = (Element) list.item(0); Text text = (Text) element.getFirstChild(); String value = text.getNodeValue(); return value; } public static void addTextNode(Document doc, Element parent, String elementName, String elementValue){ Element element = doc.createElement(elementName); parent.appendChild(element); Text text = doc.createTextNode(elementName); text.setNodeValue(elementValue); element.appendChild(text); } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 41 The XMLUtil class (continued) public static void writeDocumentToFile(String xmlFile, Document doc) throws TransformerException { DOMSource in = new DOMSource(doc); File xmlFileObj = new File(xmlFile); StreamResult out = new StreamResult(xmlFileObj); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "4"); transformer.transform(in, out); } } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 42 The UserXML class package data; import import import import import import import import import import org.xml.sax.*; org.w3c.dom.*; javax.xml.transform.*; javax.xml.transform.dom.*; javax.xml.transform.stream.*; javax.xml.parsers.*; java.io.*; java.util.Vector; business.User; util.XMLUtil; public class UserXML{ Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 43 The UserXML class (continued) public synchronized static boolean isMatch( String emailAddress, String xmlFile) throws IOException, ParserConfigurationException, SAXException { Document doc = XMLUtil.getDocumentFromFile(xmlFile); NodeList emailElements = doc.getElementsByTagName("emailAddress"); for (int i = 0; i < emailElements.getLength(); i++){ Text textNode = (Text) emailElements.item(i).getFirstChild(); if (textNode.getNodeValue().equalsIgnoreCase( emailAddress)){ return true; } } return false; } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 44 The UserXML class (continued) public synchronized static void addRecord(User user, String xmlFile) throws IOException, SAXException, ParserConfigurationException, TransformerException{ Document doc = XMLUtil.getDocumentFromFile(xmlFile); Element userElement = doc.createElement("User"); userElement.setAttribute("contact", "yes"); XMLUtil.addTextNode(doc, userElement, "firstName", user.getFirstName()); XMLUtil.addTextNode(doc, userElement, "lastName", user.getLastName()); XMLUtil.addTextNode(doc, userElement, "emailAddress", user.getEmailAddress()); Element root = doc.getDocumentElement(); root.appendChild(userElement); XMLUtil.writeDocumentToFile(xmlFile, doc); } }//contains other methods that delete and update records Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 45 The doGet method of the EmailServlet class public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ String file = "../webapps/murach/WEB-INF/etc/users.xml"; String firstName = request.getParameter("firstName"); String lastName = request.getParameter("lastName"); String emailAddress = request.getParameter("emailAddress"); User user = new User(firstName, lastName, emailAddress); HttpSession session = request.getSession(); session.setAttribute("user", user); String message = ""; Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 46 The doGet method (continued) try{ //check whether the email address already exist boolean emailExists = UserXML.isMatch(emailAddress, file); if (emailExists){ message = "This email address already " + "exists. <br>Please enter " + "another email address."; session.setAttribute("message", message); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( "/email16/join_email_list.jsp"); dispatcher.forward(request, response); } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 47 The doGet method (continued) else{ UserXML.addRecord(user, file); session.setAttribute("message", ""); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( "/email16/show_email_entry.jsp"); dispatcher.forward(request, response); } } catch(Exception e){ message = "EmailServlet Exception: " + e; session.setAttribute("message", message); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( "/email16/join_email_list.jsp"); dispatcher.forward(request, response); } } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 48 The code for the XMLServlet class package email16; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class XMLServlet extends HttpServlet{ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/xml"); File file = new File( "../webapps/murach/WEB-INF/etc/users.xml"); FileInputStream in = new FileInputStream(file); PrintWriter out = response.getWriter(); Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 49 The XMLServlet class (continued) int i; while ((i = in.read()) != -1) out.write(i); in.close(); } } Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 50 The XML file displayed in a browser Java Servlets and JSPCH16 © 2003, Mike Murach & Associates, Inc. Slide 51