Modifying XML Documents

In the previous chapter, we saw that the Java DOM parser has several methods , such as insertBefore and addChild , that let you modify a document in memory. SAX parsers don't give you access to the whole document tree at once, so no similar methods exist here.

However, you can "modify" the structure of a document when using a SAX parser simply by calling various callback methods yourself. For example, you can modify ch12_01.xml to create ch12_11.xml, adding a <MIDDLE_NAME> element with the text "XML" to each <PERSON> element in addition to the <FIRST_NAME> and <LAST_NAME> elements. It's easy enough to do the same here using SAX methods. All I have to do is to wait for a <FIST_NAME> element and then "create" a new element by calling the startElement , characters , and endElement callbacks myself :

 public void endElement(String uri, String localName, String qualifiedName)  {     indent = indent.substring(0, indent.length() - 4);     displayStrings[numberDisplayLines] = indent;     displayStrings[numberDisplayLines] += "</";     displayStrings[numberDisplayLines] += qualifiedName;     displayStrings[numberDisplayLines] += '>';     numberDisplayLines++;  if (qualifiedName.equals("FIRST_NAME")) {   startElement("", "MIDDLE_NAME", "MIDDLE_NAME", null);   characters("XML".toCharArray(), 0, "XML".length());   endElement("", "MIDDLE_NAME", "MIDDLE_NAME");   }  } 

In the main method, I'll write this new document out to ch12_11.xml:

 public static void main(String args[])      {         displayDocument(args[0]);  try {   FileWriter filewriter = new FileWriter("ch12_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);   }  } } 

And that's ithere's the whole code:

Listing ch12_10.java
 import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.*; import java.io.*; public class ch12_10 extends DefaultHandler {     static String displayStrings[] = new String[1000];     static int numberDisplayLines = 0;     static String indent = "";     public void displayDocument(String uri)     {         DefaultHandler handler = this;         SAXParserFactory factory = SAXParserFactory.newInstance();         try {             SAXParser saxParser = factory.newSAXParser();             saxParser.parse(new File(uri), handler);         } catch (Throwable t) {}     }     public void startDocument()     {         displayStrings[numberDisplayLines] = indent;         displayStrings[numberDisplayLines] += "<?xml version=\"1.0\" encoding=\""+             "UTF-8" + "\"?>";         numberDisplayLines++;     }     public void processingInstruction(String target, String data)     {         displayStrings[numberDisplayLines] = indent;         displayStrings[numberDisplayLines] += "<?";         displayStrings[numberDisplayLines] += target;         if (data != null && data.length() > 0) {             displayStrings[numberDisplayLines] += ' ';             displayStrings[numberDisplayLines] += data;         }         displayStrings[numberDisplayLines] += "?>";         numberDisplayLines++;     }     public void startElement(String uri, String localName, String qualifiedName,         Attributes attributes)     {         displayStrings[numberDisplayLines] = indent;         indent += "    ";         displayStrings[numberDisplayLines] += '<';         displayStrings[numberDisplayLines] += qualifiedName;         if (attributes != null) {             int numberAttributes = attributes.getLength();             for (int loopIndex = 0; loopIndex < numberAttributes; loopIndex++) {                 displayStrings[numberDisplayLines] += ' ';                 displayStrings[numberDisplayLines] += attributes.getLocalName(loopIndex);                 displayStrings[numberDisplayLines] += "=\"";                 displayStrings[numberDisplayLines] += attributes.getValue(loopIndex);                 displayStrings[numberDisplayLines] += '"';             }         }         displayStrings[numberDisplayLines] += '>';         numberDisplayLines++;     }     public void characters(char characters[], int start, int length)     {         String characterData = (new String(characters, start, length)).trim();         if(characterData.indexOf("\n") < 0 && characterData.length() > 0) {             displayStrings[numberDisplayLines] = indent;             displayStrings[numberDisplayLines] += characterData;             numberDisplayLines++;         }     }     public void ignorableWhitespace(char characters[], int start, int length)     {         //characters(characters, start, length);     }     public void endElement(String uri, String localName, String qualifiedName)     {         indent = indent.substring(0, indent.length() - 4);         displayStrings[numberDisplayLines] = indent;         displayStrings[numberDisplayLines] += "</";         displayStrings[numberDisplayLines] += qualifiedName;         displayStrings[numberDisplayLines] += '>';         numberDisplayLines++;         if (qualifiedName.equals("FIRST_NAME")) {             startElement("", "MIDDLE_NAME", "MIDDLE_NAME", null);             characters("XML".toCharArray(), 0, "XML".length());             endElement("", "MIDDLE_NAME", "MIDDLE_NAME");         }     }     public void warning(SAXParseException exception)     {         System.err.println("WARNING! " +             exception.getMessage());     }     public void error(SAXParseException exception)     {         System.err.println("ERROR! " +             exception.getMessage());     }     public void fatalError(SAXParseException exception)     {         System.err.println("FATAL ERROR! " +             exception.getMessage());     }     public static void main(String args[])     {         ch12_10 obj = new ch12_10();         obj.displayDocument(args[0]);         try {             FileWriter filewriter = new FileWriter("ch12_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);         }     } } 

And here's what the resulting document, ch12_11.xml, looks like, with the new <MIDDLE_NAME> elements:

Listing ch12_11.xml
 <?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>                     Lettuce                 </PRODUCT>                 <NUMBER>                     6                 </NUMBER>                 <PRICE>                     .50                 </PRICE>             </ITEM>         </ORDERS>     </CUSTOMER> </DOCUMENT> 

That finishes our work with the Java XML parsers for the moment. In the next chapter, I'm going to start working with XSL transformations.



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