Basic SAX
There are currently two published versions of the SAX API. We'll use version 2 (see Resources) for our examples. Version 2 uses different class and method names than version 1, but the structure of the code is the same.
SAX is an API, not a parser, so this code is generic across XML parsers. To get the examples to run, you will need to access an XML parser that supports SAX v2. I use Apache's Xerces parser. (See Resources.) Review your parser's getting-started guide for specifics on invoking a SAX parser.
The SAX API specification is pretty straightforward. In includes many details, but its primary task is to create a class that implements the
ContentHandler interface, a callback interface used by XML parsers to notify your program of SAX events as they are found in the XML document.The SAX API also conveniently supplies a
DefaultHandler implementation class for the ContentHandler interface.Once you've implemented the
ContentHandler or extended the DefaultHandler, you need only direct the XML parser to parse a particular document.Our first example extends the
DefaultHandler to print each SAX event to the console. This will give you a feel for what SAX events will be generated and in what order.To get started, here's the sample XML document we will use in our first example:
<?xml version="1.0"?>
<simple date="7/7/2000" >
<name> Bob </name>
<location> New York </location>
</simple>Next, we see the source code for XML mapping code of the first example:
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;
public class Example1 extends DefaultHandler {
// Override methods of the DefaultHandler class
// to gain notification of SAX Events.
//
// See org.xml.sax.ContentHandler for all available events.
//
public void startDocument( ) throws SAXException {
System.out.println( "SAX Event: START DOCUMENT" );
}
public void endDocument( ) throws SAXException {
System.out.println( "SAX Event: END DOCUMENT" );
}
public void startElement( String namespaceURI,
String localName,
String qName,
Attributes attr ) throws SAXException {
System.out.println( "SAX Event: START ELEMENT[ " +
&nbs p; localName + " ]" );
// Also, let's print the attributes if
// there are any...
for ( int i = 0; i < attr.getLength(); i++ ){
&nbs p; System.out.println( " ATTRIBUTE: " +
&nbs p; attr.getLocalName(i) +
&nbs p; " VALUE: " +
&nbs p; attr.getValue(i) );
}
}
public void endElement( String namespaceURI,
String localName,
String qName ) throws SAXException {
System.out.println( "SAX Event: END ELEMENT[ " +
&nbs p; localName + " ]" );
}
public void characters( char[] ch, int start, int length )
&nbs p; throws SAXException {
System.out.print( "SAX Event: CHARACTERS[ " );
try {
OutputStreamWriter outw = new OutputStreamWriter(System.out);
outw.write( ch, start,length );
outw.flush();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println( " ]" );
}
public static void main( String[] argv ){
System.out.println( "Example1 SAX Events:" );
try {
// Create SAX 2 parser...
XMLReader xr = XMLReaderFactory.createXMLReader();
// Set the ContentHandler...
xr.setContentHandler( new Example1() );
// Parse the file...
xr.parse( new InputSource(
new FileReader( "Example1.xml" )) );
}catch ( Exception e ) {
e.printStackTrace();
}
}
}Finally, here is the output generated by running the first example with our sample XML document:
Example1 SAX Events:
SAX Event: START DOCUMENT
SAX Event: START ELEMENT[ simple ]
ATTRIBUTE: date VALUE: 7/7/2000
SAX Event: CHARACTERS[
]
SAX Event: START ELEMENT[ name ]
SAX Event: CHARACTERS[ Bob ]
SAX Event: END ELEMENT[ name ]
SAX Event: CHARACTERS[
]
SAX Event: START ELEMENT[ location ]
SAX Event: CHARACTERS[ New York ]
SAX Event: END ELEMENT[ location ]
SAX Event: CHARACTERS[
]
SAX Event: END ELEMENT[ simple ]
SAX Event: END DOCUMENTAs you can see, the SAX parser will call the appropriate
ContentHandler method for every SAX event it discovers in the XML document.