The first
task in any process involving JDOM is to obtain a JDOM
Document
object. The
Document
object in JDOM is the core class that represents an XML document.
Like all other objects within the JDOM model, the org.jdom.Document
class is detailed in Appendix A, and all its method signatures are listed. Additionally, complete Javadoc on JDOM is available at http://www.jdom.org.
There are two ways to obtain a JDOM Document
object: create one from scratch, when no existing XML data must be
read, and build one from existing XML data.
When no existing XML data is needed as
a starting point, creating a JDOM Document
is
simply a matter of invoking a constructor:
Document doc = new Document(new Element("root"));
As we mentioned earlier, JDOM is a set of concrete classes, not a set
of interfaces. This means that the more complicated code using
factories to create objects as needed to create an
org.w3c.dom.Element
in DOM is unnecessary in JDOM.
We simply perform the new
operation on the
Document
object, and we have a viable JDOM
Document
that can be used.
This Document
is not tied to any particular
parser, either. XML often needs to be created from a blank template,
rather than an existing XML data source, so there is a JDOM
constructor for org.jdom.Document
that requires
only a root Element
as a parameter. Example 8.3 builds an XML document from scratch using
JDOM.
Example 8-3. Building a Document
import org.jdom.Document; import org.jdom.Element; /** * <p> * Demonstrate building a JDOM Document from scratch. * </p> * * @version 1.0 */ public class FromScratch { /** * <p> * Build a simple XML document in memory. * </p> */ public static void main(String[] args) { Document doc = new Document(new Element("root")); System.out.println("Document successfully built"); } }
This creates a new JDOM Document
object with a new
Element
as its root (using the name
“root” for the Element
). This
Document
can be used for any purpose, manipulated
in memory, and later output to a stream.
As simple as creating a JDOM
Document
from no previous data is, it is more
common to have existing data that needs to be read. Because JDOM
documents may be created from many sources, a separate package is
provided with classes for generating a
JDOM
Document
object from these various forms of input.
This package,
org.jdom.input
, defines the
Builder
interface, whose methods are shown in
Example 8.4.
Example 8-4. The org.jdom.input.Builder Interface
public interface Builder { // Create a JDOM Document from an InputStream public Document build(InputStream in) throws JDOMException; // Create a JDOM Document from a File public Document build(File file) throws JDOMException; // Create a JDOM Document from a URL public Document build(URL url) throws JDOMException; }
This provides a mechanism for a JDOM Document
to
be created from various input sources, and for different
implementations to be built for various input formats. Currently,
JDOM provides two builder implementations,
SAXBuilder
and
DOMBuilder
.[6] These allow current standards-based parsers to be used
for creating JDOM Document
objects, without those
parsers having to provide additional support to their current DOM and
SAX offerings.
Using the
org.jdom.input.SAXBuilder
class to create a JDOM document from an
existing XML input source is fairly simple. The
SAXBuilder
constructor can take in
two optional parameters: the name of the SAX parser class to use
(which should implement org.xml.sax.XMLReader
),
and a flag indicating whether validation should occur. If neither is
supplied, the default parser is used (currently Apache Xerces), and
validation does not occur. We can create a simple
SAXTest
class to allow entry of a file on the
command line, and then create a JDOM Document
object using the SAXBuilder
class and the supplied
filename:
import java.io.File; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.Builder; import org.jdom.input.SAXBuilder; public class SAXTest { public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: SAXTest [filename to parse]"); return; } try { // Request document building without validation Builder builder = new SAXBuilder(false); Document doc = builder.build(new File(args[0])); System.out.println("Document successfully read"); } catch (JDOMException e) { e.printStackTrace( ); } } }
Seems simple, doesn’t it? This is because the
SAXBuilder
handles the chores of creating the
various SAX handler classes, registering those with the
XMLReader
implementation, and building the JDOM
Document
. This is similar to how many DOM parsers
might build a DOM Document
object using SAX;
however, to keep things simple, JDOM’s
SAXBuilder
handles all
SAXException
s and converts them to
JDOMException
s. This isolates the SAX code from
your Document
building, and JDOM ensures the
converted exceptions contain information about the specific problems
that occurred in parsing and the line on which they occurred.
The
org.jdom.input.DOMBuilder
class is almost identical in function to
the SAXBuilder
class. Like
SAXBuilder
, it provides a means of producing a
JDOM Document
, but uses DOM and DOM parsers to
accomplish the task. Because DOM does not define a standard parser
interface, the
org.jdom.adapters
package supplies an abstraction level
over vendor-specific parsers, providing a standard means of obtaining
a DOM Document
object. The constructor of a
DOMBuilder
takes in a flag indicating whether
validation should occur, as well as the name of the adapter class to
use. This can be any class (including user-defined ones), as long as
it implements the DOMAdapter
interface defined in
org.jdom.adapters
.
While the org.jdom.adapters
package was created for use with JDOM, it can also be used in pure DOM applications as a flexible JAXP alternative. It provides a complete abstraction over the DOM parsing process, allowing the input of an InputStream
or filename, as well as a validation flag, and will return a constructed DOM Document
object. In other words, you could use these adapter classes in your applications to prevent having to import DOM-specific parser implementations. Additionally, the adapter classes are all built on reflection, so they do not require any parser implementations to be in your classpath at compile-time. This allows complete configurability and portability of an application with regard to the DOM parser implementation used.
Once the DOMBuilder
has been created, it functions
exactly the same as the SAXBuilder
. The following
example shows how to build a Document
using DOM:
import java.io.File; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.Builder; import org.jdom.input.DOMBuilder; public class DOMTest { public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: DOMTest [filename to parse]"); return; } try { // Request document building without validation, using Oracle parser Builder builder = new DOMBuilder("org.jdom.adapters.OracleV2DOMAdapter"); Document doc = builder.build(new File(args[0])); System.out.println("Document successfully read"); } catch (JDOMException e) { e.printStackTrace( ); } } }
This uses the Oracle V2 XML parser to create a DOM tree, and then
build a JDOM Document
object from that DOM tree.
To use the default parser, simply call Builder
builder
=
new DOMBuilder( )
.
All current DOM parser implementations actually use SAX to create a DOM tree. For this reason, using DOMBuilder
to create a JDOM Document
object does not make much sense; it will always be slower than SAXBuilder
(as SAX is used in both cases), and will always consume more memory, as the complete DOM tree exists for the duration of the conversion process into JDOM. DOMBuilder
, then, should rarely be used. Its main value is the method it provides to create a JDOM Document
object from an existing DOM tree (such as one received as input to your application from a non-JDOM application). This method, build(org.w3c.dom.Document)
, is detailed in Appendix A.
Once the JDOM Document
object has been created,
there is no difference in the Document
operation
and functionality between varying builders.
[6] By the time you are
reading this, it is possible that JDOM 1.0 will have additional
Builder
implementations available. While the 1.0
core API was frozen at the time of this writing, the helper packages
(org.jdom.input
,
org.jdom.output
, and
org.jdom.adapters
) were not. This allows for
enhancements that do not affect the core API to be added during the
book’s publication cycle. Check http://www.jdom.orgfor updates.
18.219.142.20