The Node interface available when you use the DOM parser contains all the standard W3C DOM methods for navigating in a document, such as getNextSibling , getPreviousSibling , getFirstChild , getLastChild , and getParent . It's different when you use a SAX parser: This parser does not create a tree of nodes, so those methods don't apply. Instead, if you want to find a particular element, you have to find it yourself. In the previous chapter, I found the third person's name in this document, which we'll call ch12_08.xml here: Listing ch12_08.xml<?xml version="1.0"?> <MEETINGS> <MEETING TYPE="informal"> <MEETING_TITLE>XML In The Real World</MEETING_TITLE> <MEETING_NUMBER>2079</MEETING_NUMBER> <SUBJECT>XML</SUBJECT> <DATE>6/1/2002</DATE> <PEOPLE> <PERSON ATTENDANCE="present"> <FIRST_NAME>Edward</FIRST_NAME> <LAST_NAME>Samson</LAST_NAME> </PERSON> <PERSON ATTENDANCE="absent"> <FIRST_NAME>Ernestine</FIRST_NAME> <LAST_NAME>Johnson</LAST_NAME> </PERSON> <PERSON ATTENDANCE="present"> <FIRST_NAME>Betty</FIRST_NAME> <LAST_NAME>Richardson</LAST_NAME> </PERSON> </PEOPLE> </MEETING> </MEETINGS> It's not difficult to do the same thing here, but in SAX programming, finding a specific element takes a little code. I start by finding the third <PERSON> element and setting a variable named thirdPersonFlag to true when I find it: public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) { if(qualifiedName.equals("PERSON")) { personCount++; } if(personCount == 3) { thirdPersonFlag = true; } . . . } When the SAX parser is parsing the third person's <FIRST_NAME> element, I'll set a variable named firstNameFlag to true . When it's parsing the third person's <LAST_NAME> element, I'll set a variable named lastNameFlag to true: public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) { if(qualifiedName.equals("PERSON")) { personCount++; } if(personCount == 3) { thirdPersonFlag = true; } if(qualifiedName.equals("FIRST_NAME") && thirdPersonFlag) { firstNameFlag = true; } if(qualifiedName.equals("LAST_NAME") && thirdPersonFlag) { firstNameFlag = false; lastNameFlag = true; } } Watching the variables firstNameFlag and lastNameFlag , I can store the person's first and last names in the character callback: 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) { if(firstNameFlag) { firstName = characterData; } if(lastNameFlag) { lastName = characterData; } } } When the SAX parser is done parsing the third <PERSON> element, I'll display that person's name: public void endElement(String uri, String localName, String qualifiedName) { if(thirdPersonFlag && lastNameFlag){ System.out.println("Third name: " + firstName + " " + lastName); thirdPersonFlag = false; firstNameFlag = false; lastNameFlag = false; } } And that's the technique you use when you're hunting a specific element using a SAX parser. You just wait until the parser hands it to you. Here are the results: %java ch12_09 ch12_08.xml Third name: Betty Richardson Here's the full code for this program, ch12_09.java: Listing ch12_09.javaimport org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.*; import java.io.*; public class ch12_09 extends DefaultHandler { int personCount; boolean thirdPersonFlag = false, firstNameFlag = false, lastNameFlag = false; String firstName, lastName; 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 startElement(String uri, String localName, String qualifiedName, Attributes attributes) { if(qualifiedName.equals("PERSON")) { personCount++; } if(personCount == 3) { thirdPersonFlag = true; } if(qualifiedName.equals("FIRST_NAME") && thirdPersonFlag) { firstNameFlag = true; } if(qualifiedName.equals("LAST_NAME") && thirdPersonFlag) { firstNameFlag = false; lastNameFlag = true; } } 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) { if(firstNameFlag) { firstName = characterData; } if(lastNameFlag) { lastName = characterData; } } } public void endElement(String uri, String localName, String qualifiedName) { if(thirdPersonFlag && lastNameFlag){ System.out.println("Third name: " + firstName + " " + lastName); thirdPersonFlag = false; firstNameFlag = false; lastNameFlag = false; } } 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_09 obj = new ch12_09(); obj.displayDocument(args[0]); } } |