XML with Java and JDOM
Posted by ObLiB on August 29, 2008
A few months ago, I worked on a java project which had to manage XML data. The XML data that I had to deal with weren’t very complex so I try to find the easiest way to manage XML data with Java and I found JDOM.
We want to provide a solution for using XML from Java that is as simple as Java itself.
There is no compelling reason for a Java API to manipulate XML to be complex, tricky, unintuitive, or a pain in the neck. JDOMTM is both Java-centric and Java-optimized. It behaves like Java, it uses Java collections, it is completely natural API for current Java developers, and it provides a low-cost entry point for using XML.
While JDOM interoperates well with existing standards such as the Simple API for XML (SAX) and the Document Object Model (DOM), it is not an abstraction layer or enhancement to those APIs. Rather, it provides a robust, light-weight means of reading and writing XML data without the complex and memory-consumptive options that current API offerings provide.
JDOM is a Java API developed regardless of Sun Microsystems. It can handle XML data more simply than with conventional API. Its use is convenient for any Java developer and is based on Sun’s XML API.
Let’s show you an example to see how it works...
First of all you need to download and install JDOM. Go to http://www.jdom.org/dist/binary/ and download jdom-1.1. Then unzip it and make the build/jdom.jar file accessible trought to the classpath (if you are under Eclipse you simply have to configure the build path of your project with “Add External Archives...” and select jdom.jar).
Now we are ready to use JDOM. We will create a XML file from scratch. You just have to build your XML tree by adding elements one to the other. A node is a org.jdom.Element instance.
Let’s create a JDOMDVD class which will create the following XML tree:
<dvd_collection>
<dvd_list genre="action">
<dvd>
<title>Die Hard</title>
<year>1988</year>
</dvd>
<dvd_list>
<dvd_collection>
import java.io.FileOutputStream;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
public class JDOMDVD {
// Create the XML root Element
static Element root = new Element("dvd_collection");
// Create a JDOM Document based on the root Element
static Document document = new Document(root);
public static void main(String[] args) {
// Create a new "dvd_list" Element
// that we will add to the root Element
Element actionDvdList = new Element("dvd_list");
root.addContent(actionDvdList);
// Create a new Attribute and add it
// to the actionDvdList Element
Attribute genre = new Attribute("genre","action");
actionDvdList.setAttribute(genre);
// Create a new "dvd" Element and add it
// to the actionDvdList Element
Element dvd = new Element("dvd");
actionDvdList.addContent(dvd);
// Create a new "title" Element, set its text,
// and add it to the dvd Element
Element dvdTitle = new Element("title");
dvdTitle.setText("Die Hard");
dvd.addContent(dvdTitle);
// Create a new "year" Element, set its text,
// and add it to the dvd Element
Element dvdReleaseYear = new Element("year");
dvdReleaseYear.setText("1988");
dvd.addContent(dvdReleaseYear);
// show the XML output
try {
// We use classic output format with getPrettyFormat()
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
xmlOutputter.output(document, System.out);
}
catch (java.io.IOException e) {
e.printStackTrace();
}
// Save it to a "dvd.xml" file
try {
// We use classic output format with getPrettyFormat()
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
xmlOutputter.output(document, new FileOutputStream("dvd.xml"));
}
catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
The result:
<?xml version="1.0" encoding="UTF-8"?>
<dvd_collection>
<dvd_list genre="action">
<dvd>
<title>Die Hard</title>
<year>1988</year>
</dvd>
<dvd_list>
<dvd_collection>
I said you that it was easy !
Now let’s see how it works with exisiting XML files. We will parse a XML file to a JDOM tree. To do this, we’ll use the org.jdom.input.SAXBuilder class, based on the SAX API...
First, create the following XML file in your JDOMDVD class directory. Let’s call it “dvd_collection.xml”
<?xml version="1.0" encoding="UTF-8"?>
<dvd_collection>
<dvd_list genre="action">
<dvd>
<title>Die Hard</title>
<year>1988</year>
</dvd>
<dvd>
<title>Die Hard 2</title>
<year>1990</year>
</dvd>
<dvd>
<title>Die Hard with a Vengeance</title>
<year>1995</year>
</dvd>
<dvd>
<title>Die Hard 4.0</title>
<year>2007</year>
</dvd>
</dvd_list>
<dvd_list genre="comedy">
<dvd>
<title>There’s Something about Mary</title>
<year>1998</year>
</dvd>
<dvd>
<title>Monty Python and the Holy Grail</title>
<year>1975</year>
</dvd>
</dvd_list>
</dvd_collection>
We will try to show all the DVD titles from our DVD collection XML file...
Let’s create the JDOMDVDTitles class:
import java.io.File;
import javax.swing.JFileChooser;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class JDOMDVDTitles {
static Document document;
static Element root;
public static void main(String[] args) {
// Create a SAXBuilder instance
SAXBuilder sxb = new SAXBuilder();
// Dialog to choose the XML file to parse
JFileChooser jfc = new JFileChooser(".");
int result = jfc.showOpenDialog(null);
switch(result) {
case JFileChooser.APPROVE_OPTION:
try {
// Create a new JDOM document from a XML file
File file = jfc.getSelectedFile();
System.out.println("Parsing "+file+"...");
document = sxb.build(file);
// Parsing done !
}
catch(Exception e) {
e.printStackTrace();
}
break;
case JFileChooser.CANCEL_OPTION:
System.out.println("Operation canceled...");
System.exit(0);
break;
case JFileChooser.ERROR_OPTION:
System.out.println("!! An error has occured !!");
System.exit(0);
break;
}
// Initialize the root Element with the document root Element
try {
root = document.getRootElement();
}
catch(NullPointerException e) {
e.printStackTrace();
}
// Browse the XML tree to retrieve dvd titles
for(Object dvd_list : root.getChildren("dvd_list")) {
Element courant = (Element) dvd_list;
for(Object dvd : courant.getChildren("dvd")) {
Element dvdElt = (Element) dvd;
System.out.println(dvdElt.getChild("title").getText());
}
}
}
}
Here is the output:
Parsing D:\eclipse3.4\workspace\JDOM\dvd_collection.xml ...
Die Hard
Die Hard 2
Die Hard with a Vengeance
Die Hard 4.0
There’s Something about Mary
Monty Python and the Holy Grail
As easy as our first example ! Now let’s do something a little more complex...
We will try to make a filtered search on our DVD collection: Let’s find the “action” movies from 1995 and more. To do this, we will use the org.jdom.filter.Filter interface
import java.io.File;
import javax.swing.JFileChooser;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.filter.Filter;
import org.jdom.input.SAXBuilder;
public class JDOMDVDFilter {
static Document document;
static Element root;
public static void main(String[] args) {
// Create a SAXBuilder instance
SAXBuilder sxb = new SAXBuilder();
// Dialog to choose the XML file to parse
JFileChooser jfc = new JFileChooser(".");
int result = jfc.showOpenDialog(null);
switch(result) {
case JFileChooser.APPROVE_OPTION:
try {
// Create a new JDOM document from a XML file
File file = jfc.getSelectedFile();
System.out.println("Parsing "+file+"...");
document = sxb.build(file);
// Parsing done !
}
catch(Exception e) {
e.printStackTrace();
}
break;
case JFileChooser.CANCEL_OPTION:
System.out.println("Operation canceled...");
System.exit(0);
break;
case JFileChooser.ERROR_OPTION:
System.out.println("!! An error has occured !!");
System.exit(0);
break;
}
// Initialize the root Element with the document root Element
try {
root = document.getRootElement();
}
catch(NullPointerException e) {
e.printStackTrace();
}
// Create a new Filter
Filter myDvdFilter = new Filter() {
// Define filter properties with the ‘matches’ method
public boolean matches(Object ob) {
// Check ob is an Element
if(!(ob instanceof Element)){return false;}
Element element = (Element) ob;
boolean genreChecked = false;
boolean yearChecked = false;
if(element.getParentElement() != null) {
// Check genre = "action"
genreChecked = element.getParentElement().getAttributeValue("genre").equals("action");
// Check date >= 1995
yearChecked = Integer.parseInt(element.getChild("year").getText()) >= 1995;
}
return genreChecked && yearChecked;
}
};
// Browse "dvd" item and do a Filtered search
System.out.println("------\nFiltered Search...");
for(Object object : root.getChildren("dvd_list")) {
Element dvdList = (Element) object;
// Browse the list of "dvd" Element matching our Filter
for(Object searchResultOb : dvdList.getContent(myDvdFilter)) {
Element dvd = (Element) searchResultOb;
System.out.println(dvd.getChild("title").getText());
}
}
}
}
Here is the result:
Parsing D:\eclipse3.4\workspace\JDOM\dvd_collection.xml ...
------
Filtered Search...
Die Hard with a Vengeance
Die Hard 4.0
I only show you the basics functionalities of JDOM, just to show you its simplicity.
I invite you to take a look to the JDOM API Documentation to learn more about it



Recent Links Tagged With "gettext" - JabberTags said
[...] on Tue 30-12-2008 No gettext support for PHP5 in Gentoo Saved by fncll on Mon 29-12-2008 XML with Java and JDOM Saved by tunaranch on Sun 28-12-2008 WordPress 2.6.1 Saved by rplaw on Thu 25-12-2008 Larry [...]
anon said
Have you looked at vtd-xml? it is a lot faster and memory efficient than DOM4J and JDOM
vtd-xml
jzhang said
VTD-XML is 10x faster and 5x more memory efficient than JDOM
or DOM4J
vtd-xml