October 1, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

JDOM: XML Meets Java Meets Open Source

  • January 3, 2001
  • By Piroz Mohseni
  • Send Email »
  • More Articles »

XML is an extensible framework for encapsulating data. Its widespread usage has depended to a large degree on how various programming languages could support reading, writing, and manipulating XML. Standards like DOM and SAX were developed early on and provide a language-independent API for XML manipulation. As the technology matures, issues such as performance, ease of use, and productivity become important. While many consider XML the universal language for data, there is no such thing as a universal programming language. Different languages have different capabilities and are optimized for certain tasks. While DOM and SAX continue to dominate the development world, new language-specific APIs are emerging. One such API is JDOM, an open source project whose goal is to make XML manipulation easier for Java programmers. This article is an introduction to JDOM.

JDOM takes an intuitive approach to XML manipulation. All XML building blocks (node types) are represented in JDOM as a class. For example, an element, an attribute, or a processing instruction, all have a corresponding class in JDOM. Using an underlying SAX or DOM parser, an XML document is parsed and represented as a Document object. The root element of the Document object is your key to gaining access to the rest of the XML document. Since Java naturally supports object inheritance, you are able to navigate the object hierarchy representing your XML document and extract the information you want. There is no event model to follow or DOM tree nodes to traverse. Your interaction with the XML document is done via Java objects (something that is very familiar to Java programmers).

The API is actually quite simple. The org.jdom.input package handles SAX or DOM input by offering a SAXBuilder and a DOMBuilder class. The org.jdom.output package wraps XMLOutput, DOMOutput, and SAXOutput classes which allow you to export XML as XML, DOM tree or a stream of SAX events respectively. The org.jdom.adapters package contain a series of adapter classes for various XML parsers that can be plugged into JDOM. Finally, the org.jdom package includes the classes representing the familiar XML building blocks: Attribute, CDATA, Comment, DocType, Document, Element, Entity, Namespace, and ProcessingInstruction.

Reading and Writing

Let's jump into an example right away. Listing 1 shows an Echo program that parses an XML file and then writes it out to the console.

Listing 1.

import java.io.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;

public class EchoXML {
    public static void main(String[] args) {
          
          try {
              SAXBuilder saxbuild = new SAXBuilder();
              DOMBuilder dombuild = new DOMBuilder();

              Document d = saxbuild.build(new File(args[0]));
              Document d2 = dombuild.build(new File(args[0]));
            
              XMLOutputter xmlout = new XMLOutputter("%%%%%");
              xmlout.output(d, System.out);

              System.out.println("\n----------------------------");

              xmlout.setTrimText(true);
              xmlout.setIndent(false);

              xmlout.output(d2, System.out);
         }
         catch (Exception ex) {
              ex.printStackTrace();
         }
    }
}

We used both the SAXBuilder and the DOMBuilder to parse the incoming XML document. If performance is a concern to you, you should use the SAXBuilder. If you need to validate the XML document, you can specify a Boolean "true" as a parameter in the

build()
method. After the parsing is done, we produce two outputs. When using XMLOutputter, you can turn indentation on or off, specify a string that will be used for indentation and indicate whether new lines should be inserted or removed. We just used a couple of these methods for demonstration purposes in the above example.

In order to compile and run the above code, you need to download JDOM. At the time of writing of this article the latest version was JDOM Beta 5. After you unzip (or untar) the file, go to the build directory. You will find the jdom.jar file there which needs to be added to your CLASSPATH. You will also see a build.bat (or build.sh) file. By running this file, you can rebuild the jdom.jar file. You should also build the API documentation files by typing

build javadoc

at the command prompt. With the jdom.jar file in your CLASSPATH and the documentation at hand, you are ready to use JDOM. Go ahead and compile the above the program and run it with a sample XML file.

Data Extraction

Reading and writing is easy. Most of the challenge comes when programs need to manipulate XML data. JDOM addresses this issue by providing an object representation of the XML document which act as your interface to the information contained in the XML document as well as its structure. To demonstrate some of the capabilities, assume that we have a file containing some customer information as shown in Listing 2.

Listing 2.




 John 
  Doe 

1234 Long Street
Chicago IL 87654

We also have a number of files each containing information about a product that we sell. These files are numbered item1.xml, item2.xml, item3.xml, etc. Here is an example:


Telephone
49.99
TEL-8760
1

We want to write a program that will read all the "item" files specified on the command line, determine which ones are in-stock, and then output a new XML file containing the order, which includes the customer information plus the items that will be shipped. This requires the program to read and parse various XML files, extract information from them and then put elements from different files together to create a new XML output. Listing 3 shows one way this can be done using the JDOM API.

Listing 3.

import java.io.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;

public class Order {
        public static void main(String[] args) {
              try {
                    SAXBuilder builder = new SAXBuilder();
                    Document customerdoc = builder.build("customer.xml");
                    Element customer = customerdoc.getRootElement();
                    Element fname = (Element)
                                customer.getChild("name").getChild("first").clone();
                    Element lname = (Element)
                                customer.getChild("name").getChild("last").clone();
                    Element address = (Element)
                                customer.getChild("address").clone();
                    Element city = (Element) customer.getChild("city").clone();
                    Element state = (Element) customer.getChild("state").clone();
                    Element zipcode = (Element) customer.getChild("zipcode").clone();

                    Element order = new Element("order");
                    order.addContent(fname);
                    order.addContent(lname);
                    order.addContent(address);
                    order.addContent(city);
                    order.addContent(state);
                    order.addContent(zipcode);

                    Document orderdoc = new Document(order);
                    orderdoc.setRootElement(order);

                    Document itemdoc;
                    String instock;
                    Element item;
                    for (int x=0; x 

After we parse the customer.xml file, we use the

getRootElement()
method to grab the root element of the document. This is stored in the variable customer. We can then use the
getChild()
method to navigate through the document and retrieve other elements of the file. We are using the
clone()
method to do a deep copy of the extracted elements because we want to then append these to our output file. In other words, we don't want the elements to maintain their original relationships to their parents as we transfer them to the new file. Once we have the various elements from the customer.xml as independent "Element" objects, we create a new Element called "order" which is going to be the root element of our output document. Using the
addContent()
method, we add some elements to the "order" and build our hierarchy using familiar Java constructs.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel