Jason Hunter and Brett McLaughlin created JDOM as an open source project, but it has since been accepted as a Java Specification Request (JSR-102). At the time of writing this book, the expert group for this specification was still being formed, and only the release candidate v. 0.8 of the original code was available. This version has undergone significant changes from v. 0.7, and we believe it will evolve further as a JSR. This section gives an overview of this technology as it exists with v. 0.8.
JDOM came into being because Java developers really needed a straightforward model that abstracted the complexities of dealing with XML and performed well. It is similar to DOM in that it represents a tree structure, but it is not built on W3C DOM and does not use any of the DOM IDL constructs (and hence the Java bindings defined in the org.w3c.dom package). It is essentially an API used to represent an XML data tree in a format optimized for Java. From an implementation perspective, JDOM differs from DOM in the following major respects:
It uses only concrete classes rather than interfaces.
It makes extensive use of the Java collection classes.
It does not require a DOM parser. It uses a SAX parser for parsing and validating an input XML document, though it can also take a previously constructed DOM as input. JDOM is not a parser; it is an XML representation model in Java.
It includes converters to output a JDOM representation as a SAX2 event stream, a DOM model, or an XML text document.
Figure 9.10 represents the core JDOM classes in v. 0.8.
The apparent difference between DOM in Figure 9.3 and Figure 9.10 is that all the representations are classes (that implement Serializable and Cloneable) and do not inherit from a base class (such as Node in DOM). There are also no list classes, such as SAX's Attribute or DOM's NodeList and NamedNodeMap classes; the Java collections in java.util.collections (List, Map, etc.) are used instead. For example, when getAttributes() is invoked on an Element, a List is returned, as opposed to a NamedNodeMap in DOM. This simplifies a lot of things for the developer.
The good thing about having concrete classes is that they eliminate the need for factories to instantiate them. For example, a DOM can be constructed directly using the following code:
Element root = new Element("flutebank"); Element admin = new Element("administrator"); admin.setText("John Malkovich"); root.addContent(admin); Document doc = new Document(root);
The output from the above would look like this:
JDOM classes can also be subclassed into application-specific classes that handle specific processing tasks. For example, Element could be subclasssed into a Person, which could be subclassed into Employee and Manager by an application that held different sorting and access logic.
JDOM can also be used for transformations. It plugs into the JAXP transformation API by providing a custom JDOMSource and JDOMResult class. The code below shows how an XSL transformation can be applied with JDOM.
String xml = "saxexaple2.xml"; String xsl = "fluteadmin.xsl"; SAXBuilder builder = new SAXBuilder(); // Note this is a JDOM Document not a W3C DOM Document object Document doc = builder.build(xml); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer= factory.newTransformer(new StreamSource(new File( xsl))); transformer.transform(new JDOMSource(doc), new StreamResult(System.out));
The above code also demonstrates how JDOM relies on the builder classes; the two most often used are SAXBuilder and DOMBuilder, which construct a JDOM representation from set of SAX events or a DOM tree.
We envision that as the JDOM model is standardized under the Java community process, the transformation part will probably be plugged under the JAXP layer as another implementation (like XSLTc). Although JDOM holds tremendous promise, considering the early stage of the specification, it would be prudent to wait for a final version to be released as a standard Java extension API before embracing this technology completely.