Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Take the sting out of SAX

Generate SAX parsers with XML Schemas

  • Print
  • Feedback

Page 3 of 4

Listing 3. Event handler template

package ${package};
// JDK Classes
import java.util.*;
import java.io.*;
// Xerces Classes
import org.xml.sax.*;
import org.apache.xerces.parsers.*;
import org.xml.sax.helpers.DefaultHandler;
public class ${element.Name}handler extends DefaultHandler
{
    private CharArrayWriter text = new CharArrayWriter ();
    private Stack path;
    private Map params;
    private DefaultHandler parent;
    private SAXParser parser;
    public ${element.Name}handler(Stack path, Map params, Attributes attributes, SAXParser parser, DefaultHandler parent)  throws SAXException
    {
        this.path = path;
        this.params = params;
        this.parent = parent;
        this.parser = parser;
        start(attributes);
    }
    
## Some code omitted
    public void endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName) throws SAXException
    {
        if (qName.equals("${element.Name}"))
        {
            end();
            path.pop();
            parser.setContentHandler (parent);
        }
        #foreach ($child in $element.Children)
          #if ($child.hasChildren())
          #else
            if (qName.equals("${child.Name}")) end${child.Name} ();
          #end
        #end
    }


The second class template is the entry point for the SAX parser and is responsible for initialization tasks and for calling the root element's handler:

Listing 4. The parser template

## Some code omitted
    public void startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, Attributes attributes) throws SAXException
    {
        if (qName.equals("${elements.RootElement.Name}"))
        {
            DefaultHandler handler = new ${elements.RootElement.Name}handler(path,params,attributes,parser,this);
            path.push ("${elements.RootElement.Name}");
            parser.setContentHandler (handler);
        }
    }
## Some code omitted


The controller class

Now we simply put everything together in a controller class (download the class's source code from Resources). A controller class handles the process's logic—see the MVC (Model-View-Controller) model.

Called Generator, the controller class requires two command-line parameters. The first parameter indicates the XML Schema to use, and the second gives the output classes' package name. Generator then loads the XML Schema into memory and executes the source code templates.

With the Generator class, you can easily create a SAX parser. To illustrate how to use the SAX generator, let's create a SAX parser for Listing 1's XML. I include that listing's XML Schema (example1.xsd) in Resources as well as the SAX generator's source and binary versions. Before you use the SAX generator's prepackaged binary version, read the readme.txt file for usage directions and required external jar libraries. Also, make sure you correctly set your $JAVA_HOME environment variable. Now you can use generate.bat (for Windows machines) or generate.sh (for Unix/Linux machines) to start the SAX generator. To create a SAX parser for example1.xsd, execute one of the following on the command line:

For Windows:

generate examples\example-1.xsd com.mycompany.package


For Unix/Linux:

./generate.sh examples/example-1.xsd com.mycompany.package     


The first parameter indicates the XML Schema the program should use to build the SAX parser; the second parameter indicates the Java package name for the new classes.

  • Print
  • Feedback

Resources
  • "Programming XML in Java," Mark Johnson (JavaWorld):