Right at the beginning of this chapter we introduced the notion of an XML processor as a module that is used by an application to read XML documents. An XML processor parses the contents of a document and makes the elements together with their attributes and content available to the application, so it is also referred to as an XML parser. In case you haven't met the term before a parser is just a program module that breaks text in a given language down into its component parts. A natural language processor would have a parser that identifies the grammatical segments in each sentence. A compiler has a parser that identifies variables, constants, operators, etc. in a program statement. An application accesses the content of a document through an API provided by an XML parser and the parser does the job of figuring out what the document consists of.
Java supports two complementary APIs for processing an XML document:
SAX, which is the Simple API for XML parsing.
DOM, which is the Document Object Model for XML.
The support in SDK 1.4 is for DOM level 2 version 1 and for SAX version 2. SDK 1.4 also supports XSLT version 1.0 where XSL is the eXtensible Stylesheet Language and T is Transformations – a language for transforming one XML document into another, or into some other textual representation such as HTML. However, we will concentrate on the basic application of DOM and SAX. XSLT is such an extensive topic that there are several books devoted entirely to it.
For more information on XSLT please refer to XSLT Programmer's Reference 2nd Edition, by Michael H. Kay, Wrox Press Ltd., (ISBN 1-861005-06-7).
Before we get into detail on these APIs, let's look at the broad differences between SAX and DOM, and get an idea of the circumstances in which you might choose to use one rather than the other.
SAX uses an event-based process for reading an XML document that is implemented through a callback mechanism. This is very similar to the way in which we handle GUI events in Java. As the parser reads a document, each parsing event, such as recognizing the start or end of an element, results in a call to a particular method that is associated with that event. Such a method is often referred to as a handler. It is up to you to implement these methods to respond appropriately to the event. Each of your methods then has the opportunity to react to the event that will result in it being called in any way that you wish. Below you can see the events that would arise from the XML document example that we saw earlier.
Each type of event results in a different method in your program being called. There are, for instance, different events for registering the beginning and end of a document. You can also see that the start and end of each element result in two further kinds of events, and another type of event occurs for each segment of document data. Thus this particular document will involve five different methods in your program being called – some of them more than once, of course, so there is one method for each type of event.
Because of the way SAX works, your application inevitably receives the document a piece at a time, with no representation of the whole document. This means that if you need to have the whole document available to your program with its elements and content properly structured you have to assemble it yourself from the information supplied to your callback methods.
Of course, it also means that you don't have to keep the entire document in memory if you don't need it, so if you are just looking for particular information from a document, all <phonenumber> elements for instance, you can just save those as you receive them through the callback mechanism, and discard the rest. As a consequence, SAX is a particularly fast and memory efficient way of selectively processing the contents of an XML document.
First of all, SAX itself is not an XML document parser; it is a public domain definition of an interface to an XML parser, where the parser is an external program. The public domain part of the SAX API is in three packages that are shipped as part of the SDK:
org.xml.sax – this defines the Java interfaces specifying the SAX API and the InputSource class that encapsulates a source of an XML document to be parsed.
org.xml.sax.helpers – this defines a number of helper classes for interfacing to a SAX parser.
org.xml.sax.ext – this defines interfaces representing optional extensions to SAX2 to obtain information about a DTD, or to obtain information about comments and CDATA sections in a document.
In addition to these, the javax.xml.parsers package provides factory classes that you use to gain access to a parser and the javax.xml.transform package defines interfaces and classes for XSLT 1.0 processing of an XML document.
In Java terms there are several interfaces involved. The XMLReader interface that is defined in the org.xml.sax package specifies the methods that the SAX parser will call as it recognizes elements, attributes, and other components of an XML document. You must provide a class that implements these methods and responds to the method calls in the way that you want.
DOM works quite differently to SAX. When an XML document is parsed, the whole document tree is assembled in memory and returned to your application as an object of type Document that encapsulates it, as illustrated below.
Once you have the Document object available you can call the object's methods to navigate through the elements in the document tree starting with the root element. With DOM, the entire document is available to you for you to process as often and in as many ways as you want. This is a major advantage over SAX processing. The downside to this is the amount of memory occupied by the document – there is no choice, you get it all no matter how big it is. With some documents the amount of memory required may be prohibitively large.
DOM has one other unique advantage over SAX. It allows you to modify existing documents or create new ones. If you want to create an XML document programmatically and then transfer it to an external destination such as a file or another computer, DOM is the API for this since SAX has no direct provision for creating or modifying XML documents. We will go into detail on how we can use a DOM parser in the next chapter.