You can read and manipulate XML documents in Java much easier by using XmlBeans. We show you how to get started.

XML may be human readable but it can be a tedious chore writing code to read and manipulate it. For the lazily efficient coder, tedious chores are not for them, and thanks to XmlBeans and E4X, a lot of those chores can be eliminated.

Let's start with XmlBeans, now at version 2.0. XmlBeans originated within BEA and was donated to Apache. The world is full of XML/Java data binding tools; what makes XmlBeans different is that it is useful to many if not most classes of XML related coding, from low level node traversal over non-data elements (so you can dig out those comments programmatically) to abstracted data oriented manipulation.

Working with XmlBeans starts with an XML Schema. Let's take an example schema for a simple application, sites.xsd. You'll find this, with the rest of the examples in this article in the download for this article.

Our example schema specifies a schema with a "sites" element, which can contain a number of "site" elements, which in turn can contain any number of "rating" or "comment" elements which both have an email address as an attribute for identifying the author of the rating or comment.

Get XmlBeans from the Apache Web site and install it. Remember to set the enviroment variable XMLBEANS_HOME to where you install it and add the $XMLBEANS_HOME/bin directory from the distribution to your path. This will make the XmlBeans commands available, most important of these being "scomp", the schema compiler.

Now if we run

scomp -out sites.jar sites.xsd

We get to see

Time to build schema type system: 1.185 seconds Time to generate code: 0.131 seconds Time to compile code: 1.179 seconds Compiled types to: sites.jar

Scomp has built a type system, generated Java code for it and compiled it. We only get a sites.jar file as output because unless told not to, scomp just generates the precompiled jar file. If you want to see the source of the code it generates, you can run

scomp -srconly -src srcdir sites.xsd

Now we can see what has been created. The generated classes are all in the com.example.sites.site package; this has been derived from the target namespace of the schema. This is defined in the opening lines of the schema file:

<?xml version="1.0" encoding="utf-8"?>
<?xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:si="http://www.example.com/sites/SITE"

    targetNamespace="http://www.example.com/sites/SITE"
    elementFormDefault="qualified">

If your schema doesn't have a target namespace, the generated classes will appear in a package called noNamespace. For the example, we have a SitesDocument class, and classes for each of the types defined in the schema, Sites, Site, Comment, Rating and Email. All of these generated classes extend the XmlBeans foundation class, XmlObject. We'll get back to that but for now we'll get straight to parsing a XML document...

import com.example.sites.site.*;
import java.io.*;
import org.apache.xmlbeans.*;
public class Example1 {
    public static void main(String[] args) {
      try {
        SitesDocument sd=SitesDocument.Factory.parse(new
          File("./sites.xml"));
        /* ......... */
      }
      catch (IOException e) {
        System.err.println("IOException:"+e);
      }
      catch (XmlException e) {
        System.err.println("XmlException:"+e);
      }
    }
}

...and that's it. Problems in parsing will throw an XmlException. We are ready to do some processing. All of the generated classes have a static Factory to allow for the creation of instances, either by parsing or programmatic creation. Here we've used the simplest parse method in the factory.

Let's add some code to iterate through the site entries and print out the comments and ratings. First we need to get the root element of our document.

Sites sites=sd.getSites();

Sequences in XML Schemas are represented by arrays in XmlBeans, so we can take that array and iterate through it (note that we're using Java SE 5.0's new for construct);

for(Site s:sites.getSiteArray()) {

Elements and their attributes have methods generated for them to allow you to get and set their values; let's get the src attribute of our site and print it.

System.out.println(s.getSrc());

And in the same way, we can get the Rating and Comment arrays within the Site element and iterate through them.

for(Rating r:s.getRatingArray()) {
  System.out.println(r.getEmail() + " rated the site "
    + r.getRated() + " on " + r.getRatedon());
}
for(Comment c:s.getCommentArray()) {
  System.out.println(c.getEmail() + " said "
    + c.getStringValue());
  }
}

Do you need help with XML? Gain advice from Builder AU forums

Related links

Comments

1

Rick Simms - 03/11/05

I always get an IO exception - even if I include my sdk bin and xml bin in a -cp parameter - in your example I used
scomp -out sites.jat sites.xsd
and
scomp -cp C:\j2sdk1.4.2_09\bin;D:\xmlbeans-2.0.0\bin -out sites.jat sites.xsd

I always get -

Time to build schema type system: 1.057 seconds
Time to generate code: 0.17 seconds
java.io.IOException: CreateProcess: D:\XMLExamples\xmlbnat\javac @D:\DOCUME~1\dz
8fnk\LOCALS~1\Temp\javac62757 error=2
null
java.io.IOException: CreateProcess: D:\XMLExamples\xmlbnat\javac @D:\DOCUME~1\dz
8fnk\LOCALS~1\Temp\javac62757 error=2
at java.lang.Win32Process.create(Native Method)
at java.lang.Win32Process.(Unknown Source)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at org.apache.xmlbeans.impl.tool.CodeGenUtil.externalCompile(CodeGenUtil
.java:229)
at org.apache.xmlbeans.impl.tool.SchemaCompiler.compile(SchemaCompiler.j
ava:1121)
at org.apache.xmlbeans.impl.tool.SchemaCompiler.main(SchemaCompiler.java
:367)
BUILD FAILED

-------------------------------------------------

I have been able to open the temp file - add spaces for example it has -dD:\DOCUME~1\dz8fnk\LOCALS~1\Temp\xbean5761.d\cl****es

I add spaces before or after switches file names etc and get it to at least compile with javac.

Any help would be appreciated - with this method I do not get the jar and when I try to create/run code it can not find the import for apache.

» Report offensive content

2

Gaurav Saxena - 24/07/06

I get the same exception while working with xmlbeans2.2.0
here is the exception trace

        at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at org.apache.xmlbeans.impl.tool.CodeGenUtil.externalCompile(CodeGenUtil
.java:231)
at org.apache.xmlbeans.impl.tool.SchemaCompiler.compile(SchemaCompiler.j
ava:1126)
at org.apache.xmlbeans.impl.tool.SchemaCompiler.main(SchemaCompiler.java
:368)
BUILD FAILED

» Report offensive content

Leave a comment

You must read and type the 6 chars within 0..9 and A..F

* indicates mandatory fields.

2

Gaurav Saxena - 24/07/06

I get the same exception while working with xmlbeans2.2.0 here is the exception trace ... more

1

Rick Simms - 11/03/05

I always get an IO exception - even if I include my sdk bin and xml bin in a -cp parameter ... more

Log in


Sign up | Forgot your password?

  • Staff Apple to developer: Fart jokes aren't funny

    When Apple announced it would be vetting every application submitted for inclusion in the App Store, this was just the kind of question that entered many a mind: just how arbitrary would the company be in wielding that veto power? Read more »

    -- posted by Staff

  • Staff Chrome is just another browser

    Hands up if you missed the Chrome release -- didn't think anyone did. Google's browser arrived with all the fanfare and hype that only Google can produce. Read more »

    -- posted by Staff

  • Renai LeMay 2Vouch refers well

    Melbourne-based Web start-up 2Vouch yesterday launched the first public beta of what it dubs its "social recruiting platform". Read more »

    -- posted by Renai LeMay

What's on?