The Document Object Model
The DOM, unlike SAX, has its origins in the World Wide Web Consortium (W3C; online at http://www.w3.org). Whereas SAX is public domain software, developed through long discussions on the XML-dev mailing list, DOM is a standardjust like the actual XML specification. The DOM is designed to represent the content and model of XML documents across all coding languages and tools. On top of that specification, there are several language bindings. These bindings exist for JavaScript, Java, CORBA, and other languages, allowing the DOM to be a cross-platform and cross-language specification.
DOM Levels and Modules
In addition to being different from SAX in regard to standardization and language bindings, the DOM is organized into "levels" instead of versions. DOM Level One is an accepted recommendation, and you can view the completed specification at http://www.w3.org/TR/REC-DOM-Level-1. Level 1 details the functionality and navigation of content within a document.
|
DOM Level 2, which was finalized in November of 2000, adds core functionality to DOM Level 1. There are also several additional DOM modules and options aimed at specific content models, such as XML, HTML, and CSS. These less-generic modules begin to "fill in the blanks" left by the more general tools provided in DOM Level 1. You can view the current DOM Level 2 Recommendation at http://www.w3.org/TR/DOM-Level-2-Core. This is actually the recommendation for the DOM Core; all the supplemental modules are represented by their own specifications:
DOM Level 2 Views (http://www.w3.org/TR/DOM-Level-2-Views)
-
The Views module deals with interaction between an XML document and some type of stylesheet or presentation aspect. For instance, the same XML document could be styled by multiple CSS or XSL stylesheets; each of the resulting documents would be a view. It turns out that this module isn't that useful, as Java tools for document transformation are plentiful; most parsers won't support this module.
DOM Level 2 Events (http://www.w3.org/TR/DOM-Level-2-Events)
-
The Events module provides a DOM-centric event model for XML documents. You can register event listeners for specific DOM Nodes (more on the Node class later), and then write code that is triggered when, for example, the data in that Node changes. While some parsers support the complete Events module, manylike Apache Xercesonly provide support for mutation events, that is, events that are triggered by the changing of document data. This is plenty for most apps that need event support.
|
DOM Level 2 Styles (http://www.w3.org/TR/DOM-Level-2-Style)
-
The Styles module provides a DOM-centric model for accessing CSS stylesheets, as well as other DOM stylesheets (called DOM style sheets by the specification). Since these are more concerned with HTML and presentation issues, most XML parsers don't support the Styles module.
DOM Level 2 Traversal and Range (http://www.w3.org/TR/DOM-Level-2-Traversal-Range)
-
The Traversal and Range module is probably of the most interest to Java developers. It allows access and selection of a DOM tree (and subsets of that tree) in ways more interesting and flexible than the core DOM module allows. You can select ranges of Nodes easily and manipulate them as a whole. As you might expect, the more popular XML parsers support this module as a general rule.
DOM Level 2 HTML (http://www.w3.org/TR/DOM-Level-2-HTML)
-
The HTML module provides a HTML (and XHTML) semantic veneer over DOM. You can access HTML elements as HTMLHead and HTMLLink instead of DOM Elements named head and link; this is incredibly handy if you do lots of HTML work. If you want to use the DOM HTML module, you'll probably want to check out Tidy (http://tidy.sf.net), a program specifically aimed at working with HTML.
The most recent entrant on the DOM scene, DOM Level 3 is a recommendation that builds upon the DOM Level 2 core. It's housed online at http://www.w3.org/TR/DOM-Level-3-Core, and is mostly concerned with adding support for the XML InfoSet to DOM. However, it also provides a nice bootstrapping implementation, which you'll see in more detail later in this chapter. Support for DOM Level 3 in parsers is a bit sporadic, and you'll often see only portions of the specification implemented (bootstrapping being the most common one).
|
There are also two new modules introduced by DOM Level 3:
DOM Level 3 Load and Save (http://www.w3.org/TR/DOM-Level-3-LS)
-
There is no secret about what the Load and Save module does, is there? This adds the much-needed ability to load and serialize XML documents, via DOM, in a vendor-neutral manner. Without this class, you're forced to use parser-specific tools for writing out DOM documents.
DOM Level 3 Validation (http://www.w3.org/TR/DOM-Level-3-Val)
-
The Validation module allows an in-memory DOM document to be validated. Even more important, you can set up checks to ensure that changes to the document are allowed only if the document remains valid. This is a module that I've rarely seen implemented, as it's pretty tricky to get right. Expect it to be late-coming, but very popular when it finally shows up.
|
To try and serve the general Java and XML community, I'm largely sticking to DOM Level 2 Core in this chapter; while DOM Level 3 is locked down, parsers have been slow to pick up support for it. That said, I will cover DOM Level 3 bootstrapping, but you'll need to make sure your parser supports the functionality I describe before diving in. For best results, use the latest version of Apache Xerces; when using Xerces directly, I'm using Version 2.6.2, and when using Xerces through JAXP (see Chapters 7 and 8), I'm using the version bundled with Java 5.0, which gives me support for:
- DOM Core Level 1 and 2
- DOM Core Level 3 (in so-called experimental fashion)
- DOM Level 2 Traversal and Range
- DOM Level 2 Mutation Events (the mutation portion of the Events module)
- DOM Level 3 Load and Save (again, in experimental fashion)
DOM Concepts
In addition to fundamentals about the DOM specification, I want to give you a bit of information about the DOM coding structure itself. At the core of DOM is a tree model. Remember that SAX gave you a piece-by-piece view of an XML document, reporting each event in the parsing lifecycle as it happened. DOM is in many ways the converse of this, supplying a complete in-memory representation of the document. The document is supplied to you in a tree format, and all of this is built upon the DOM org.w3c.dom.Node interface. Deriving from this interface, DOM provides several XML-specific interfaces, like Element, Document, Attr, and Text. So, in a typical XML document, you might get a structure that looks like .
DOM documents are often called trees, for reasons obvious from this diagram

A tree model is followed in every sense. This is particularly notable in the case of the Element nodes that have textual values (as in the Title element). Instead of the textual value of the node being available through the Element node (through, for example, a getText( ) method), there is a child node of type Text. So you would get the value of an element from the child Text node, rather than the Element node itself. While this might seem a little odd, it does preserve a very strict tree model in DOM, and allows tasks like walking the tree to be very simple algorithms, without a lot of special cases. Because of this model, all DOM structures can be treated either as their generic type, Node, or as their specific type (Element, Attr, etc.). Many of the navigation methods, like getParent( ) and getChildren( ), operate on that basic Node interface, so you can walk up and down the tree without worrying about the specific structure type. Another facet of DOM to be aware of is that, like SAX, it defines its own list structures. You'll need to use the NodeList and NamedNodeMap classes when working with DOM lists, rather than Java collections. Depending on your point of view, this isn't a positive or negative, just a fact of life. shows a simple UML-style model of the DOM core interfaces and classes, which you can refer to throughout the rest of the chapter.
Most of the DOM model deals with XML representation; there are also a few exceptions and list classes

When SAX Sucks
There are a lot of times when using DOM isn't a choice, but a requirement. You'd do well to recognize those situations quickly, and not waste time trying to decide which API to use. Here are the times you essentially must use DOM:
You need random access to your document
-
In SAX, you get information about the XML document as the parser does, and lose that information when the parser does. When the second element in a document comes along, SAX cannot access information in the fourth element, because that fourth element hasn't been parsed yet. When the fourth element does come along, SAX can't look back on that second element.
You need access to siblings of an element
-
Moving laterally between elements is also difficult with the SAX parsing model. The access provided in SAX is largely hierarchical, as well as sequential. You are going to reach leaf nodes of the first element, then move back up the tree, then down again to leaf nodes of the second element, and so on. At no point is there any clear indication of what level of the hierarchy you are at. There is no concept of a sibling element, or of the next element at the same level, or of which elements are nested within which other elements.
These are hardly indictments of SAX; rather, they are issues that affect what API you use for a specific app. While the above issues are shortcomings for representing, say, an HTML document that must be styled with an XSL stylesheet, they are advantages for extracting data from a 10,000 line catalog entry where you don't need random access to the document.