XML Made Easy with XMLBeans

very once in a while there comes around a tool so useful it makes you wonder why nobody ever did it before, or why it hasn’t been a part of the technology since its inception. Such a tool is XMLBeans, an XML parser developed by BEA for WebLogic 8.1 and recently released as an open source initiative.

We’ve all used parsers and APIs for handling XML, and there is no shortage of them. XMLBeans is different from the typical XML parser because it is designed to build applications based on known, specific schemas. At its core is a schema compiler that parses an XSD file and creates a JAR. The JAR contains a bunch of Java classes that developers can use to manipulate instance documents as if they were normal Java types.

XMLBeans gives you an object-based view of the underlying XML data, without losing access to the original XML structure. It may appear to be similar to the APIs that allow you to map Java classes to document elements, but it differs in one major aspect: It doesn’t take the XML apart in order to bind to its parts. With XMLBeans you handle the entire instance document as a whole, or you can create instance documents in Java by manipulating the classes that have been built for you by the XMLBeans compiler. You do this via regular bean-like access, using get and set methods.

In addition, it gives you an XQuery parser and XMLCursor objects that allow you to query your documents with the flexibility of a SQL database.

Getting Started: Building the Schema
Any XMLBeans project begins with a schema. The point of XMLBeans is to give you a toolkit that allows you to quickly build applications that can efficiently manipulate XML data. Therefore, it is logical to begin with a definition of that data, and that is exactly what an XML schema is. Generally an XML schema is stored in an XSD file.

An example of a very simple schema, which holds name and address details for an individual is shown here.

                    

This schema is effectively a template describing how your valid XML should appear. It is a simple case where you have an element that should be called AddressDetails containing a number of child elements called Name, Address1, Address2, ZIP, and Email, each of which are defined as strings (xs:string) for validation purposes.

Author’s Note: XML schema support a large number of data types and element types; listing them is beyond the scope of this article. A good place to start investigating XML schema is the W3C’s XML schema namespace located at http://www.w3.org/2001/XMLSchema.

The schema above declares the location (http://tempuri.org/AddressDetails.xsd ) of the ‘xs’ namespace definition, and any element names beginning with ‘xs:’ belong to the namespace defined at that location. Therefore elements such as ‘xs:string’ and ‘xs:sequence’ are defined there, and you may use that as a reference point in trying to understand them. You will be looking at a neat feature of XMLBeans that adds support for these data types a little later on.

Building Your First XMLBean
Before you begin you will of course need the XMLBeans development kit from BEA. The downloadable ZIP file includes everything you need to get started. Download it from http://dev2dev.bea.com/technologies/xmlbeans/overview.jsp. Unzip the file and you will get a directory structure as in Figure 1.

To install the development kit, you must follow these steps.

  • If you don’t have it already, download and install a version of Java 2 Standard edition SDK version 1.4 or later from http://java.sun.com.
  • Make sure that J2SE is installed and that the JAVA_HOME environment variable points to the installation. JAVA_HOME/bin should contain at least java.exe, javac.exe, and jar.exe for XMLBeans to work properly.
  • Create an XMLBEANDIR environment variable and point it to the directory containing xbean.jar. In the example from Figure 1, this value would be C:xmlbeansxkitlib
  • Add the XMLBeans ‘bin’ directory to your path (example: C:xmlbeansxkitin).
Figure 1. Unzipped: The default directory structure in the XMLBeans SDK is shown.

Open a DOS command prompt and run the ‘scomp’ command. If it runs without error, then congratulations, you have successfully set up XMLBeans.

When you have reached this stage, building your first XMLBean is very simple. In the ‘Schemas’ directory, create a new subdirectory called AddressDetails. Take the AddressDetails.XSD from the download for this article and put it in this directory.

Open a DOS prompt and change to the directory containing AddressDetails.XSD.

Issue the following command:

	     Scomp AddressDetails.xsd out AddressDetails.jar

If all goes well you should see this message:

     Loading schema file AddressDetails.xsd     Time to build schema type system: 0.851 seconds     Time to generate code: 1.983 seconds     Compiled types to AddressDetails.jar

You will now have a JAR file containing the classes necessary to process or create XML documents that are defined by the schema.

Using the XMLBean to Create XML
Creating XML with the XMLBean is very easy. You simply create instances of the object that represents your data and add them to the object that represents your document. It’s far easier than it sounds.

If you are using an IDE to create your Java file, you will have to add references to the jar file containing the XMLBeans (that you just created), and to the xbean.jar, which is in the xmlbeansxkitlib directory.

When writing your Java code, you will need to reference two classes, the AddressDetailsDocument and the AddressDetails.

import org.tempuri.addressDetails.AddressDetailsDocument;import org.tempuri.addressDetails.AddressDetailsDocument.AddressDetails;
Author’s Note: The documentation that comes with XMLBeans has a walkthrough that uses a purchase order schema and demonstrates some sample code to allow you to process purchase orders. There are some bugs in this code, particularly with the imports, and these can be misleading.

One you have imported the relevant classes, you can create XML. This is simply a matter of creating an instance of the relevant document and the relevant section within the document using the appropriate classes.

AddressDetailsDocument myDoc;myDoc = AddressDetailsDocument.Factory.newInstance();AddressDetails myDetails;myDetails = myDoc.addNewAddressDetails();

Your document is created by the AddressDetailsDocument factory, calling it with the newInstance() method. You can then use the addNewAddressDetails() method on this object to create a new AddressDetails section.

This demonstrates the usefulness of the code that XMLBeans has generated for you. Instead of dealing with generic names, or having to write custom code to manage the data items that you want, the methods on the beans are named appropriately and coded for you.

To add data to the AddressDetails section, you simply call the appropriate ‘set’ methods. These methods should look familiar?they directly map to the element names defined in the schema.

myDetails.setName("Laurence Moroney");myDetails.setAddress1("123 Beverly Hills");myDetails.setAddress2("Los Angeles, CA");myDetails.setEmail("[email protected]");myDetails.setZIP("11590");

The XMLBean also provides you with ‘get’ methods that may be used to read the date, for example:

     String strName = myDetails.getName(); 

To create more, you can continually use the addNewAddressDetails method on the AddressDetailsDocument object.

Using the XMLBean to Read XML Data
Using an XMLBean to create data is useful, but in terms of what is possible, it is only the tip of the iceberg. The AddressDetailsDocument (or whatever document type is created based on your schema) has the ability to parse XML if it’s in the correct format. This instance document is built to the specification of the AddressDetails schema.

	Laurence Moroney	123 Habitat Ring 2	Deep Space Nine	11590	

This document, if stored on the hard drive, would be loaded using this code.

String strFileName = "C:\xmlbeans\xkit\schemas\Laurence\test.xml";String strXML = new String();String strReturn = "";java.io.File fleInput = new java.io.File(strFileName);try   {            AddressDetailsDocument myParsedDoc =          AddressDetailsDocument.Factory.parse(fleInput);                 AddressDetails myParsedDetails = myParsedDoc.getAddressDetails();                 strReturn = myParsedDetails.getName();   }catch(Exception e)   {      strReturn = e.toString();   }return strReturn;

The AddressDetails document has a parse method on its factory that can take xml from a variety of sources. One of these sources is a file, and in the sample code above a file is used.

One the document is initialized you can simply access the information using the getAddressDetails() method to return an AddressDetails object that may be queried for the data.

A Short Note on Data Types
Earlier in the article I mentioned the schema data types as defined by W3C.org. XMLBeans provides data types that match those definitions by providing 46 Java types that mirror the 46 built-in types defined by the XML schema specification. For example, where the W3C define an xs:int, XMLBeans gives you an XmlInt data type.

To access the data using these types you simply use the ‘xget’ method appropriate to the data that you want. So, in the above examples, if you want the XmlString associated with a name, you would use

     myParsedDetails.xgetName();

instead of

     myParsedDetails.getName();

There is a performance benefit of using the ‘xget’ version of the function as the ‘get’ version has to convert the data to the most appropriate Java type first. For more information on XML data types, please check the XMLBeans documentation.

Accessing the Data Using XQuery and XmlCursors
Another incredibly useful feature that comes with XBeans is its XQuery support. XQuery is a SQL-like language for XML that allows you to query a document to return a result set. It is defined at http://www.w3.org/TR/xquery/. (DevX has several introductory articles on XQuery; see the Related Resources, at left.)

XQuery is very easy to use in XMLBeans, as the Document object supports XmlCursors that can be created by running a query. An example of an XQuery running against your XML document is shown here:

String nsText =      "declare namespace add='http://tempuri.org/AddressDetails";String pathText = "$this/[add:name='Laurence Moroney']";String queryText = nsText + queryText;XmlCursor itemCursor = myParsedDoc.newCursor().execQuery(queryText);

You can then use the XmlCursor to navigate through the nodes that match the query in a similar fashion to a database cursor allowing you to move through a recordset. For more information on this functionality, check the documentation that came with the XMLBeans download.

XML is clearly one of the most important technologies to hit the software industry for many years. It is fantastically powerful, yet amazingly simple. To date, the tools available to Java developers to manipulate XML, while useful, have not been as intuitive as they could be. XMLBeans are a great solution to this problem, completely abstracting the implementation of the document behind a set of beans associated with the schema defining that document.

In addition, they provide many interfaces that allow you to create, parse, and query the data. They do this without impacting the underlying data, and make XML handling fast and easy while reducing the many sources of errors that are inherent in having to code your own logic to handle the contents of XML files.

This article introduced you to some of the basics. The API is now available as open source; you don’t need a WebLogic application server to run it. You can use it in your applications and make the important task of processing XML a much easier one!

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Related Posts