Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Simplify Java XML Parsing with Jakarta Digester

Jakarta's Digester maps data from an XML source to Java objects. Learn all about this package and its advantages over other similar APIs. Then follow a real life Digester parsing example.


WEBINAR: On-Demand

Unleash Your DevOps Strategy by Synchronizing Application and Database Changes REGISTER >

he Digester framework is a high-level interface that parses an XML stream and populates the data into Java objects based on rules provided to the Digester component. Among the other XML parsing options available, the Digester package offers greater simplicity. With very simple classes and a collection of predefined Rules included, Digester simplifies the parsing of complex XML schema.

Because Digester requires an XML parser that conforms to JAXP version 1.1 or later, the Digester component uses the SAX parser for the actual parsing. It is easier to use than SAX alone, however, because Digester hides all the complex parsing maintenance. The other main API for XML parsing, DOM, uses too much memory to be a practical solution for large documents—and don't you deal with large documents most of the time in the real world? Since Digester is just a layer over SAX, the difference in memory usage between DOM and Digester is the same as that between DOM and SAX. (Click here for a good comparison of the two.)

Although Digester does not perform data binding like the other options such as JAXB and XMLBeans, it provides the flexibility to create the Java classes that your architecture requires—not ones that the XML semantics demand. It allows triggers to be executed with the Rules that you provide it.

Digester Under the Hood
Digester depends on the following Jakarta Commons components, which must be in the classpath when you use Digester. (Refer to this status file page for more information about these dependencies.):

  • BeanUtils Component
  • Collections component

Using and Customizing Digester
Digester is simplest to use when you have direct mapping between the input XML stream and the Java objects.

To begin creating the Rules, you need to complete the following four steps:

  1. Identify the mapping from the source (i.e., input XML stream) to the output (i.e., the Java objects).
  2. Identify the pattern elements in the XML that contain data you need.
  3. Identify the data components that will hold the data.
  4. Create rules based on your findings and assign them to Digester.

A simple example (input.xml) should make this process clearer. Listing 1 shows the XML that you need to parse.

Listing 1. input.xml <?xml version="1.0" encoding="UTF-8"?> <response> <request> <name>books</name> <value>xml</value> </request> <matches>20</matches> </response>

Listings 2 and 3 show the Java class that you need to populate.

Listing 2. Response Class public class Response { private int _matches = 0; private Request _request; public Request getRequest() { return _request; } public void setRequest(Request request) { _request = request; } public int getMatches() { return _matches; } public void setMatches(int matches) { _matches = matches; } }

Listing 3. Request Class public class Request { private String _name = ""; private String _value = ""; public String getName() { return _name; } public void setName(String name) { _name = name; } public String getValue() { return _value; } public void setValue(String value) { _value = value; } }

Listing 4 shows the class that parses the XML using Digester. You set the Rules in Digester with this class.

Listing 4. DigesterExample Class import org.apache.commons.digester.*; import java.io.Reader; import java.io.StringReader; public class DigesterExample { public static void main(String ar[]) { try { Digester digester = new Digester(); digester.setValidating( false ); digester.addObjectCreate( "response", Response.class ); digester.addObjectCreate( "response/request", Request.class ); digester.addBeanPropertySetter("response/request/name", "name" ); digester.addBeanPropertySetter("response/request/value", value" ); digester.addSetNext( "response/request", "setRequest" ); digester.addBeanPropertySetter( "response/matches", "matches" ); Reader reader = new StringReader( "<?xml version='1.0' encoding='UTF-8'?>" + "<response>" + "<request><name>books</name><value>xml</value></request>" + "<matches>20</matches>" + "</response>"); Response response = (Response)digester.parse( reader ); System.out.println( response.toString() ); } catch( Exception exc ) { exc.printStackTrace(); } } }

Listing 4 proves how easy and straightforward using Digester is—especially when you have a direct mapping between the XML and the Java classes. (The Rules that come with the Digester package are sufficient to do the mapping and should serve as a constant reference while you read this article.) The element matching patterns within the class define when a particular Rule is fired. Each Rule extends the org.apache.commons.digester.Rule and defines the action that occurs when the rule is fired.

Comment and Contribute






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



Thanks for your registration, follow us on our social networks to keep up-to-date