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.javaimport 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. |