Reading XML Documents with JDOM


Naturally, JDOM can read existing XML documents from files, network sockets, strings, or anything else you can hook a stream or reader to. JDOM does not, however, include its own native parser. Instead it relies on any of a number of very fast, well- tested SAX2 parsers such as Xerces and Crimson.

The rough outline for working with an existing XML document using JDOM is as follows :

  1. Construct an org.jdom.input.SAXBuilder object using a simple no-args constructor.

  2. Invoke the builder's build() method to build a Document object from a Reader , InputStream , URL , File , or String containing a system ID.

  3. If there's a problem reading the document, an IOException is thrown. If there's a problem building the document, a JDOMException is thrown.

  4. Otherwise, navigate the document using the methods of the Document class, the Element class, and the other JDOM classes.

The SAXBuilder class represents the underlying XML parser. Parsing a document from a URL is straightforward. Just create a SAXBuilder object with the no-args constructor and pass the string form of the URL to its build() method. This returns a JDOM Document object. For example:

 SAXBuilder parser = new SAXBuilder();  Document doc = parser.build("http://www.cafeconleche.org/"); // work with the document... 

That's all there is to it. If you prefer, you can build the Document from a java.io.File , a java.net.URL , a java.io.InputStream , a java.io.Reader , or an org.xml.sax.InputSource .

The build() method throws an IOException if an I/O error such as a broken socket prevents the document from being read completely. It throws a JDOMException if the document is malformed . I/O errors aside, this is the generic superclass for most anything that can go wrong while working with JDOM. Example 14.7 demonstrates a simple program that checks XML documents for well- formedness by looking for these exceptions.

Example 14.7 A JDOM Program That Checks XML Documents for Well-Formedness
 import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.IOException; public class JDOMChecker {   public static void main(String[] args) {     if (args.length == 0) {       System.out.println("Usage: java JDOMChecker URL");       return;     }     SAXBuilder builder = new SAXBuilder();     // command line should offer URIs or file names     try {       builder.build(args[0]);       // If there are no well-formedness errors,       // then no exception is thrown       System.out.println(args[0] + " is well-formed.");     }     // indicates a well-formedness error     catch (JDOMException e) {      System.out.println(args[0] + " is not well-formed.");      System.out.println(e.getMessage());     }     catch (IOException e) {       System.out.println("Could not check " + args[0]);       System.out.println(" because " + e.getMessage());     }   } } 

I used this program to test my Cafe con Leche web site for well-formedness. It's supposed to be well-formed XML, but I'm often sloppy . The results were informative:

 %  java   JDOMChecker   http://www.cafeconleche.org/  http://www.cafeconleche.org is not well formed. Error on line 351 of document http://www.cafeconleche.org: The element type "img" must be terminated by the matching end-tag "</img>". 

I fixed the problem. However, JDOM only reports the first error in a document, so it's not surprising that running the program again uncovered a second problem:

 %  java   JDOMChecker   http://www.cafeconleche.org/  http://www.cafeconleche.org is not well formed. Error on line 363 of document http://www.cafeconleche.org: The element type "input" must be terminated by the matching end-tag "</input>". 

Repeatedly running the program turned up several more problems in order. Once I had fixed the last one, everything finally checked out:

 %  java   JDOMChecker   http://www.cafeconleche.org/  http://www.cafeconleche.org is well formed. 

Exactly which SAX parser JDOM uses to build documents depends on the local environment. By default, JDOM relies on JAXP to choose the parser class. If that fails, it picks Xerces. If you really care which parser is used, specify the fully package-qualified name of the XMLReader class you want as the first argument to the constructor. For example, this sets the parser as Crimson:

 SAXBuilder parser  = new SAXBuilder("org.apache.crimson.parser.XMLReaderImpl"); Document doc = parser.build("http://www.cafeconleche.org/"); // work with the document... 

By default, SAXBuilder checks documents only for well-formedness, not for validity. If you want to validate as well, then pass the boolean true to the SAXBuilder() constructor. Then any validity errors will also cause JDOMException s. Example 14.8 demonstrates with a simple validation program.

Example 14.8 A JDOM Program That Validates XML Documents
 import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.IOException; public class JDOMValidator {   public static void main(String[] args) {     if(args.length == 0) {       System.out.println("Usage: java JDOMValidator URL");       return;     }     SAXBuilder builder = new SAXBuilder(true);                                     //  ^^^^                                     // Turn on validation     // command line should offer URIs or file names     try {       builder.build(args[0]);       // If there are no well-formedness or validity errors,       // then no exception is thrown.       System.out.println(args[0] + " is valid.");     }     // indicates a well-formedness or validity error     catch (JDOMException e) {       System.out.println(args[0] + " is not valid.");       System.out.println(e.getMessage());     }     catch (IOException e) {       System.out.println("Could not check " + args[0]);       System.out.println(" because " + e.getMessage());     }   } } 

Here are the results from running this program across two documentsthe first invalid (because it doesn't even have a DTD) and the second valid:

 %  java   JDOMValidator   http://cafeconleche.org/  http://cafeconleche.org is not valid. Error on line 1 of document http://cafeconleche.org: Document root element "html", must match DOCTYPE root "null". %  java   JDOMValidator   http://www.w3.org/TR/2000/REC-xml-   20001006.html  http://www.w3.org/TR/2000/REC-xml-20001006.html is well formed. 

This does assume that the default parser that JDOM picks can in fact validate, which is true of most modern parsers you're likely to encounter. If you really want to make sure, you could always ask for a known validating parser by name. For example, the following requests the Xerces SAXParser :

 SAXBuilder parser   = new SAXBuilder("org.apache.xerces.parsers.SAXParser", true); 

Note

JDOM does not currently distinguish between validity and well-formedness errors. I'm working on a patch for this. Of course, any malformed document is de facto invalid.




Processing XML with Java. A Guide to SAX, DOM, JDOM, JAXP, and TrAX
Processing XML with Javaв„ў: A Guide to SAX, DOM, JDOM, JAXP, and TrAX
ISBN: 0201771861
EAN: 2147483647
Year: 2001
Pages: 191

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net