So far, you have learned how to access data from a DOM. The advantage that DOM provides over SAX is that you can add, modify, or delete different nodes, such as the element, comments, and so on, at any location in the DOM tree. Next, you will learn how to manipulate the DOM by adding elements, attributes, and element texts, and also how to delete a node and normalize a DOM after it has been modified. This is useful in many ways. By manipulating a DOM, you can create your own XML data from an existing document. Other uses include the capability to extract partial information from a DOM, or extracting data from a DOM based on the relationship between nodes. One important point to remember is that while DOM provides the capability to manipulate the XML data in memory, it does not provide a mechanism by which you can write the modified XML back to a file. To do that, you need to use XSLT. See Chapter 6, "XSLT and XPATH," to learn more about XSLT and how to write a DOM as an XML document. Creating Element Nodes The Document object provides a number of create methods with which you can create the different components of an XML document. For example, the createComment() method lets you create a comment node in the DOM tree. Similarly, an element node can be created by using the createElement() method. The nodes can then be added to the DOM by using either the appendChild() or insertBefore() method of the Node object. You will create a new engine element node and add it as a child node to the engines node. To do so, the following things need to be done: -
Access the engines element by using the getElementByTagNames() method. -
Create the engine element node by using the createElement() method. -
Add the engine element node as a child node to the engines element node. First, access the engines element. To do so, add the line of code listed in bold: for (int i = 0; i < ListLength; i++) { System.out.println("The name of the node is : " + list.item(i).getNodeName() + "\n"); //printDomNode(list.item(i)); Node textNode = list.item(i).getLastChild(); //Since text node is the last child node of the element node System.out.println("The value of the text node is :" + textNode.getNodeValue().trim() + "\n"); } list = document.getElementsByTagName("engines"); }catch (SAXParseException saxException) { Next, create the engine element node. To do so, add the line of code listed in bold: for (int i = 0; i < ListLength; i++) { System.out.println("The name of the node is : " + list.item(i).getNodeName() + "\n"); //printDomNode(list.item(i)); Node textNode = list.item(i).getLastChild(); //Since text node is the last child node of the element node System.out.println("The value of the text node is :" + textNode.getNodeValue().trim() + "\n"); } list = document.getElementsByTagName("engines"); Element newNode = document.createElement("engine"); }catch (SAXParseException saxException) { Finally, add the new element node as a child node to the engines element node. After you add the child node, call the printDomNode() method to verify that the node has been added successfully. To do so, add the lines of code listed in bold: for (int i = 0; i < ListLength; i++) { System.out.println("The name of the node is : " + list.item(i).getNodeName() + "\n"); //printDomNode(list.item(i)); Node textNode = list.item(i).getLastChild(); //Since text node is the last child node of the element node System.out.println("The value of the text node is :" + textNode.getNodeValue().trim() + "\n"); } list = document.getElementsByTagName("engines"); Element newNode = document.createElement("engine"); ((Element)list.item(0)).appendChild(newNode); printDomNode(list.item(0)); }catch (SAXParseException saxException) { NOTE The code discussed here is available in the example0506 folder. This folder also contains the sample CarParts.xml file. Compile and run the application. The output should be similar to that seen in Listing 5.5. Listing 5.5 Output of MyDOMHandler Application----------------- Creating the DOM from the CarParts.xml File ---------- ----------------- DOM Created from the CarParts.xml file ---------- -----------The Name of the DTD is : carparts -----------The public ID of the doctype is : CarParts.dtd ---- The tag name of the document element is : carparts ---- The number of supplier element nodes are : 1 The name of the node is : supplier The value of the text node is :Heaven Car Parts (TM) engines" [Element] #text" [Text] engine" [Element] Attr Name: capacity Value: 2500 Attr Name: id Value: E129 Attr Name: price Value: 3500 Attr Name: type Value: Alpha37 #text" [Text] #text" [Text] engine" [Element] Attr Name: capacity Value: 2500 Attr Name: id Value: E130 Attr Name: price Value: 4500 Attr Name: type Value: Beta37 #text" [Text] #text" [Text] engine" [Element] Note that the new engine element node is added as a child node to the end of the list of child nodes of the engines element node. Creating Attributes The attributes for a node can be set in a number of ways. You can use the createAttribute() method of the Document object to create an attribute, and use the setValue() method of the Attr object to set the value of the attribute. Finally, add the attribute to the element node by using the setAttributeNode() method of the Node object. A simpler process is to use the setAttribute() method of the Node object, and pass on the attribute name and its value as parameters. This creates and adds the attribute to the element in a single step. To understand how to create attributes, you will create the attributes for the engine element node by using the setAttribute() method. The attribute list in DTD for the engines element is as follows: <!ATTLIST engine id CDATA #REQUIRED type CDATA #REQUIRED capacity (1000 | 2000 | 2500 ) #REQUIRED price CDATA #IMPLIED text CDATA #IMPLIED > Update the MyDOMHandler application to add the id, type, capacity, and price attributes to the engine element node. The values for these should be ID7232, Alfa-D, 1500CC, and USD1000, respectively. To do so, add the lines of code listed in bold: list = document.getElementsByTagName("engines"); Element newNode = document.createElement("engine"); ((Element)list.item(0)).appendChild(newNode); newNode.setAttribute("id","ID7232"); newNode.setAttribute("type","Alfa-D"); newNode.setAttribute("capacity","1500CC"); newNode.setAttribute("price","USD1000"); printDomNode(list.item(0)); }catch (SAXParseException saxException) { NOTE The code discussed here is available in the example0507 folder. This folder also contains the sample CarParts.xml file. Compile and run the application. The output should be similar to that seen in Listing 5.6. Listing 5.6 Output of MyDOMHandler Application----------------- Creating the DOM from the CarParts.xml File ---------- ----------------- DOM Created from the CarParts.xml file ---------- -----------The Name of the DTD is : carparts -----------The public ID of the doctype is : CarParts.dtd ---- The tag name of the document element is : carparts ---- The number of supplier element nodes are : 1 The name of the node is : supplier The value of the text node is :Heaven Car Parts (TM) engines" [Element] #text" [Text] engine" [Element] Attr Name: capacity Value: 2500 Attr Name: id Value: E129 Attr Name: price Value: 3500 Attr Name: type Value: Alpha37 #text" [Text] #text" [Text] engine" [Element] Attr Name: capacity Value: 2500 Attr Name: id Value: E130 Attr Name: price Value: 4500 Attr Name: type Value: Beta37 #text" [Text] #text" [Text] engine" [Element] Attr Name: capacity Value: 1500CC Attr Name: id Value: ID7232 Attr Name: price Value: USD1000 Attr Name: type Value: Alfa-D Notice that the attributes you created are added to the new engine element. Creating Text Nodes The process of creating text nodes is similar to that of creating the element nodes. The Document object provides a createTextNode() method with which you can create a text node. To add text nodes to the engine element, add the lines listed in bold: list = document.getElementsByTagName("engines"); Element newNode = document.createElement("engine"); ((Element)list.item(0)).appendChild(newNode); newNode.setAttribute("id","ID7232"); newNode.setAttribute("type","Alfa-D"); newNode.setAttribute("capacity","1500CC"); newNode.setAttribute("price","USD1000"); newNode.appendChild(document.createTextNode("Engine 3")); newNode.appendChild(document.createTextNode("")); newNode.appendChild(document.createTextNode(" contd")); printDomNode(list.item(0)); }catch (SAXParseException saxException) { Notice that three text nodes were added to the engine element. Later, you will see how the three text nodes can be combined into one element by using the normalize() method. Also, make a small modification to the printDomNode() method to display the node values. To do so, add the lines of code listed in bold: public static void printDomNode(Node node) { for(int j=0;j<nodeLevel;j++) System.out.print("\t"); System.out.println(node.getNodeName() + "\" [" + nodeTypes[node.getNodeType()]+"]" + node.getNodeValue()); .......... } NOTE The code discussed here is available in the example0508 folder. This folder also contains the sample CarParts.xml file. Compile and run the application. The output should be similar to Listing 5.7. Listing 5.7 Output of MyDOMHandler Application----------------- Creating the DOM from the CarParts.xml File ---------- ----------------- DOM Created from the CarParts.xml file ---------- -----------The Name of the DTD is : carparts -----------The public ID of the doctype is : CarParts.dtd ---- The tag name of the document element is : carparts ---- The number of supplier element nodes are : 1 The name of the node is : supplier The value of the text node is :Heaven Car Parts (TM) engines" [Element]null #text" [Text] engine" [Element]null Attr Name: capacity Value: 2500 Attr Name: id Value: E129 Attr Name: price Value: 3500 Attr Name: type Value: Alpha37 #text" [Text] Engine 1 #text" [Text] engine" [Element]null Attr Name: capacity Value: 2500 Attr Name: id Value: E130 Attr Name: price Value: 4500 Attr Name: type Value: Beta37 #text" [Text] Engine 2 #text" [Text] engine" [Element]null Attr Name: capacity Value: 1500CC Attr Name: id Value: ID7232 Attr Name: price Value: USD1000 Attr Name: type Value: Alfa-D #text" [Text]Engine 3 #text" [Text] #text" [Text] contd Notice that the three text nodes you added to the engine element are displayed. Normalizing the DOM Normalizing is a process by which all the adjacent text nodes are combined into a single text node. The normalizing operation is done to ensure that the DOM tree is compact. A DOM is normalized by using the normalize() method of the Node object. To understand how to normalize the DOM, you will update the MyDOMHandler application by adding the following line of code in bold: list = document.getElementsByTagName("engines"); Element newNode = document.createElement("engine"); ((Element)list.item(0)).appendChild(newNode); newNode.setAttribute("id","ID7232"); newNode.setAttribute("type","Alfa-D"); newNode.setAttribute("capacity","1500CC"); newNode.setAttribute("price","USD1000"); newNode.appendChild(document.createTextNode("Engine 3")); newNode.appendChild(document.createTextNode("")); newNode.appendChild(document.createTextNode(" contd")); document.getDocumentElement().normalize(); printDomNode(list.item(0)); }catch (SAXParseException saxException) { Because the normalize() method is available for a node, you've obtained the root node of the document and normalized it. This ensures that all the nodes of the document are normalized. NOTE The code discussed here is available in the example0509 folder. This folder also contains the sample CarParts.xml file. Compile and run the application. The output should be similar to Listing 5.8. Listing 5.8 Output of MyDOMHandler Application----------------- Creating the DOM from the CarParts.xml File ---------- ----------------- DOM Created from the CarParts.xml file ---------- -----------The Name of the DTD is : carparts -----------The public ID of the doctype is : CarParts.dtd ---- The tag name of the document element is : carparts ---- The number of supplier element nodes are : 1 The name of the node is : supplier The value of the text node is :Heaven Car Parts (TM) engines" [Element]null #text" [Text] engine" [Element]null Attr Name: capacity Value: 2500 Attr Name: id Value: E129 Attr Name: price Value: 3500 Attr Name: type Value: Alpha37 #text" [Text] Engine 1 #text" [Text] engine" [Element]null Attr Name: capacity Value: 2500 Attr Name: id Value: E130 Attr Name: price Value: 4500 Attr Name: type Value: Beta37 #text" [Text] Engine 2 #text" [Text] engine" [Element]null Attr Name: capacity Value: 1500CC Attr Name: id Value: ID7232 Attr Name: price Value: USD1000 Attr Name: type Value: Alfa-D #text" [Text]Engine 3 contd Notice that the three text nodes for the last engine element have been combined into one text node after normalizing the document. So far, you have learned how to create an element node and add attributes and text nodes to it. You also learned how to normalize a DOM. We'll complete this chapter with an example showing the deletion of a node from a DOM tree. Deleting Nodes Similar to node creation, you can delete any node from a DOM tree by using the removeChild() method of the Node object. First, update the MyDOMHandler application to delete the carstereo element node from the DOM tree: -
Access the carstereos element node. This is the parent node of the carstereo element node. -
Access the carstereo element node. -
Remove the carstereo element node. Adding the lines of code listed here in bold will accomplish all three of these steps: list = document.getElementsByTagName("engines"); Element newNode = document.createElement("engine"); ((Element)list.item(0)).appendChild(newNode); newNode.setAttribute("id","ID7232"); newNode.setAttribute("type","Alfa-D"); newNode.setAttribute("capacity","1500CC"); newNode.setAttribute("price","USD1000"); newNode.appendChild(document.createTextNode("Engine 3")); newNode.appendChild(document.createTextNode("")); newNode.appendChild(document.createTextNode(" contd")); list = document.getElementsByTagName("carstereos"); Node tobeRmvd = list.item(0).getFirstChild().getNextSibling(); ((Element)list.item(0)).removeChild(tobeRmvd); document.getDocumentElement().normalize(); printDomNode(list.item(0)); }catch (SAXParseException saxException) { Note that the first child node of the carstereos element node is an empty text node. The carstereo element node occurs after the empty text node. Therefore, the getNextSibling() method is invoked on the empty text node to get to the carstereo element node. Then the removeChild() method is used to delete the element node from the DOM tree. NOTE The code discussed here is available in the example0510 folder. This folder also contains the sample CarParts.xml file. Compile and run the application. The output should be similar to the following: ----------------- Creating the DOM from the CarParts.xml File ---------- ----------------- DOM Created from the CarParts.xml file ---------- -----------The Name of the DTD is : carparts -----------The public ID of the doctype is : CarParts.dtd ---- The tag name of the document element is : carparts ---- The number of supplier element nodes are : 1 The name of the node is : supplier The value of the text node is :Heaven Car Parts (TM) carstereos" [Element]null #text" [Text] The carstereo element node under the carstereos element node has been deleted from the DOM tree. |