Modifying XML Documents

As you can see in Table 11-5, the Node interface contains a number of methods for modifying documents by adding or removing nodes. These methods include appendChild , insertBefore , removeChild , replaceChild , and so on. You can use these methods to modify XML documents on the fly.

If you do modify a document, however, you still have to write it out (in Chapter 7, we couldn't do that using JavaScript in a browser, so I sent the whole document to an ASP script that echoed it back to be displayed in the browser). The Java packages do support an interface named Serializer that you can use to serialize (store) documents. However, that interface is not included in the standard JAR files that we've already downloaded; in fact, it's easy enough to simply store the modified XML document ourselves because we print that document anyway. Instead of using System.out.println to display the modified document on the console, I'll use a Java FileWriter object to write that document to disk.

In this example, I'll assume that all the people listed in ch11_01.xml (you can see this document at the beginning of this chapter) are experienced XML programmers. In addition to the <FIRST_NAME> and <LAST_NAME> elements, I'll give each of them "XML" as a middle name by adding a <MIDDLE_NAME> element. Like <FIRST_NAME> and <LAST_NAME> , <MIDDLE_NAME> will be a child element of the <NAME> element:

 <NAME>      <LAST_NAME>         Jones     </LAST_NAME>     <FIRST_NAME>         Polly     </FIRST_NAME>  <MIDDLE_NAME>   XML   </MIDDLE_NAME>  </NAME> 

Adding a <MIDDLE_NAME> element to every <NAME> element is easy enough to doall I have to do is make sure we're parsing the <NAME> element and then use the createElement method to create a new element named <MIDDLE_NAME> :

 case Node.ELEMENT_NODE: {  if(node.getNodeName().equals("NAME")) {   Element middleNameElement = document.createElement("MIDDLE_NAME");  . . . 

Because all text is stored in text nodes, I also create a new text node with the createTextNode method to hold the text "XML":

 case Node.ELEMENT_NODE: {     if(node.getNodeName().equals("NAME")) {         Element middleNameElement = document.createElement("MIDDLE_NAME");  Text textNode = document.createTextNode("XML");  . . . 

Now I can append the text node to the new element with appendChild :

 case Node.ELEMENT_NODE: {     if(node.getNodeName().equals("NAME")) {         Element middleNameElement = document.createElement("MIDDLE_NAME");         Text textNode = document.createTextNode("XML");  middleNameElement.appendChild(textNode);  .     .     . 

Finally, I append the new element to the <NAME> node like this:

 case Node.ELEMENT_NODE: {     if(node.getNodeName().equals("NAME")) {         Element middleNameElement = document.createElement("MIDDLE_NAME");         Text textNode = document.createTextNode("XML");         middleNameElement.appendChild(textNode);  node.appendChild(middleNameElement);  }     .     .     . 

Using this code, I'm able to modify the document in memory. As before, the lines of this document are stored in the array displayStrings , and I can write that array to a file called ch11_11.xml. To do that, I use the Java FileWriter class, which writes text stored as character arrays in files. To create those character arrays, I can use the Java String object's handy toCharArray method, like this:

 public static void main(String args[])  {     displayDocument(args[0]);  try {   FileWriter filewriter = new FileWriter("ch11_11.xml");   for(int loopIndex = 0; loopIndex < numberDisplayLines; loopIndex++){   filewriter.write(displayStrings[loopIndex].toCharArray());   filewriter.write('\n');   }   filewriter.close();   }   catch (Exception e) {   e.printStackTrace(System.err);   }  } 

That's all there is to it. After running this code, this is the result complete with the new <MIDDLE_NAME> elements:

 <?xml version="1.0" encoding="UTF-8"?>  <DOCUMENT>     <CUSTOMER>         <NAME>             <LAST_NAME>                 Smith             </LAST_NAME>             <FIRST_NAME>                 Sam             </FIRST_NAME>  <MIDDLE_NAME>   XML   </MIDDLE_NAME>  </NAME>         <DATE>             October 15, 2003         </DATE>         <ORDERS>             <ITEM>                 <PRODUCT>                     Tomatoes                 </PRODUCT>                 <NUMBER>                     8                 </NUMBER>                 <PRICE>                     .25                 </PRICE>             </ITEM>             <ITEM>                 <PRODUCT>                     Oranges                 </PRODUCT>                 <NUMBER>                     24                 </NUMBER>                 <PRICE>                     .98                 </PRICE>             </ITEM>         </ORDERS>     </CUSTOMER>     <CUSTOMER>         <NAME>             <LAST_NAME>                 Jones             </LAST_NAME>             <FIRST_NAME>                 Polly             </FIRST_NAME>  <MIDDLE_NAME>   XML   </MIDDLE_NAME>  </NAME>         <DATE>             October 20, 2003         </DATE>         <ORDERS>             <ITEM>                 <PRODUCT>                     Bread                 </PRODUCT>                 <NUMBER>                     12                 </NUMBER>                 <PRICE>                     .95                 </PRICE>             </ITEM>             <ITEM>                 <PRODUCT>                     Apples                 </PRODUCT>                 <NUMBER>                     6                 </NUMBER>                 <PRICE>                     .50                 </PRICE>             </ITEM>         </ORDERS>     </CUSTOMER>     <CUSTOMER>         <NAME>             <LAST_NAME>                 Weber             </LAST_NAME>             <FIRST_NAME>                 Bill             </FIRST_NAME>  <MIDDLE_NAME>   XML   </MIDDLE_NAME>  </NAME>         <DATE>             October 25, 2003         </DATE>         <ORDERS>             <ITEM>                 <PRODUCT>                     Asparagus                 </PRODUCT>                 <NUMBER>                     12                 </NUMBER>                 <PRICE>                     .95                 </PRICE>             </ITEM>             <ITEM>                 <PRODUCT ID="5231" TYPE="3133">                     Lettuce                 </PRODUCT>                 <NUMBER>                     6                 </NUMBER>                 <PRICE>                     .50                 </PRICE>             </ITEM>         </ORDERS>     </CUSTOMER> </DOCUMENT> 

Here's the code for this example, ch11_10.java:

Listing ch11_10.java
 import java.awt.*; import java.io.*; import java.awt.event.*; import org.w3c.dom.*; import javax.xml.parsers.*; import org.w3c.dom.*; public class ch11_10 {     static String displayStrings[] = new String[1000];     static int numberDisplayLines = 0;     static Document document;     static Node c;     public static void displayDocument(String uri)     {         try {             DocumentBuilderFactory dbf =                 DocumentBuilderFactory.newInstance();             DocumentBuilder db = null;             try {                 db = dbf.newDocumentBuilder();             }             catch (ParserConfigurationException pce) {}             document = db.parse(uri);             display(document, "");         } catch (Exception e) {             e.printStackTrace(System.err);         }     }     public static void display(Node node, String indent)     {         if (node == null) {             return;         }         int type = node.getNodeType();         switch (type) {             case Node.DOCUMENT_NODE: {                 displayStrings[numberDisplayLines] = indent;                 displayStrings[numberDisplayLines] += "<?xml version=\"1.0\" encoding=\""+                   "UTF-8" + "\"?>";                 numberDisplayLines++;                 display(((Document)node).getDocumentElement(), "");                 break;              }              case Node.ELEMENT_NODE: {                  if(node.getNodeName().equals("NAME")) {                      Element middleNameElement =                      document.createElement("MIDDLE_NAME"); Text textNode = document. graphics/ccc.gif createTextNode("XML");                      middleNameElement.appendChild(textNode);                      node.appendChild(middleNameElement);                  }                  displayStrings[numberDisplayLines] = indent;                  displayStrings[numberDisplayLines] += "<";                  displayStrings[numberDisplayLines] += node.getNodeName();                  int length = (node.getAttributes() != null) ? node.getAttributes(). graphics/ccc.gif getLength() : 0;                  Attr attributes[] = new Attr[length];                  for (int loopIndex = 0; loopIndex < length; loopIndex++) {                      attributes[loopIndex] = (Attr)node.getAttributes().item(loopIndex);                  }                  for (int loopIndex = 0; loopIndex < attributes.length; loopIndex++) {                      Attr attribute = attributes[loopIndex];                      displayStrings[numberDisplayLines] += " ";                      displayStrings[numberDisplayLines] += attribute.getNodeName();                      displayStrings[numberDisplayLines] += "=\"";                      displayStrings[numberDisplayLines] += attribute.getNodeValue();                      displayStrings[numberDisplayLines] += "\"";                  }                  displayStrings[numberDisplayLines]+=">";                  numberDisplayLines++;                  NodeList childNodes = node.getChildNodes();                  if (childNodes != null) {                      length = childNodes.getLength();                      indent += "    ";                      for (int loopIndex = 0; loopIndex < length; loopIndex++ ) {                         display(childNodes.item(loopIndex), indent);                      }                  }                  break;              }              case Node.CDATA_SECTION_NODE: {                  displayStrings[numberDisplayLines] = indent;                  displayStrings[numberDisplayLines] += "<![CDATA[";                  displayStrings[numberDisplayLines] += node.getNodeValue();                  displayStrings[numberDisplayLines] += "]]>";                  numberDisplayLines++;                  break;              }              case Node.TEXT_NODE: {                  displayStrings[numberDisplayLines] = indent;                  String newText = node.getNodeValue().trim();                  if(newText.indexOf("\n") < 0 && newText.length() > 0) {                      displayStrings[numberDisplayLines] += newText;                      numberDisplayLines++;                  }                  break;              }              case Node.PROCESSING_INSTRUCTION_NODE: {                  displayStrings[numberDisplayLines] = indent;                  displayStrings[numberDisplayLines] += "<?";                  displayStrings[numberDisplayLines] += node.getNodeName();                  String text = node.getNodeValue();                  if (text != null && text.length() > 0) {                      displayStrings[numberDisplayLines] += text;                  }                  displayStrings[numberDisplayLines] += "?>";                  numberDisplayLines++;                  break;             }         }         if (type == Node.ELEMENT_NODE) {             displayStrings[numberDisplayLines] = indent.substring(0, indent.length() - 4);             displayStrings[numberDisplayLines] += "</";             displayStrings[numberDisplayLines] += node.getNodeName();             displayStrings[numberDisplayLines] +=">";             numberDisplayLines++;             indent += "    ";         }     }     public static void main(String args[])     {         displayDocument(args[0]);         try {             FileWriter filewriter = new FileWriter("ch11_11.xml");             for(int loopIndex = 0; loopIndex < numberDisplayLines; loopIndex++){                 filewriter.write(displayStrings[loopIndex].toCharArray());                 filewriter.write('\n');             }             filewriter.close();         }         catch (Exception e) {             e.printStackTrace(System.err);         }     } } 

As you see, there's a lot of power in Java when it comes to XML. In fact, there's another way to do all this besides using the DOM. It's called Simple API for XML (SAX), and I'll take a look at it in the next chapter.



Real World XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 440
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net