With the emergence of service-oriented architecture, most of you have had to work with XML in your applications. In doing so, you may have noticed that various models are available to parse and handle XML, both open source and proprietary. Each of these models has its advantages and disadvantages. Choosing the wrong model for your business needs can result in wasted development time and resources. Apache XMLBeans is a valuable tool that provides an easy way to work with XML from within Java. In this article, we introduce XMLBeans and some of the features available in XMLBeans 2.0.
A W3C XML Schema is an XML document that defines a set of rules other XML documents must conform to in order to be valid. W3C XML Schema has several advantages over earlier XML schema languages, such as document type definition (DTD) or simple object XML (SOX), and provides a rich collection of features you can use in different ways.
XMLBeans is a 100-percent schema-compliant XML-Java binding tool you can use to access the full power of XML in a Java-friendly way. The XMLBean solution is unique because it provides a dual view of the XML data. XMLBeans maintain the original XML document with no change in information and structure, and also provide a Java-based view of the XML data.
We will now demonstrate some of features in XMLBeans 2.0 by showing several code samples. In each sample we will provide the schema and some Java code that manipulates the XMLBean representation of the schema. The schema and Java samples will also be available for download.
Let's consider the following schema snippet:
1 <xs:element name="order"> 2 <xs:complexType> 3 <xs:sequence> 4 <xs:element name="orderNo" type="xs:string"/> 5 <xs:element name="item" nillable="true" 6 maxOccurs="unbounded" type="tns:itemType"/> 7 <xs:element name="address" type="tns:addressType"/> 8 <xs:element name="quantity" type="tns:quantityType"/> 10 </xs:sequence> 11 </xs:complexType> 12 </xs:element>
To generate XMLBeans classes, the schema needs to be compiled. This can be easily done using the
scomp utility, which will generate interfaces for all simple and complex types. The package name for all classes and interfaces is derived from the
targetNamespace value specified in the schema. For a detailed look, read Configuring XMLBeans by Hetal Shah (Dev2Dev, November 2004).
Let's now look at how to generate an instance document, check the validity of the document against the schema, and save the instance to the file system.
OrderDocument interface listed below is an example of one of the special "document" types created for any global elements or types by XMLBeans.
ItemType are interfaces created for the global complex types
1 OrderDocument orderDoc = OrderDocument.Factory.newInstance(); 2 Order order = orderDoc.addNewOrder(); 3 order.setOrderNo("ORD1234"); 4 order.setQuantity(4); 5 6 AddressType aType = order.addNewAddress(); 7 aType.setCity("Kirkland"); 8 9 ItemType iType = order.addNewItem(); 10 iType.setId("ITEM003"); 11 12 boolean isValid = orderDoc.validate(xopt); 13 14 orderDoc.save(new File("sample.xml"),xopt);
Running this sample results in the construction of an instance document that will be validated and saved to the local file system under the name "sample. xml." The program will also display the contents of this instance document and the results from the validation test to the command prompt or Unix shell:
1 <sam:order xmlns:sam="http://temp.openuri.org/Sample"> 2 <sam:orderNo>ORD1234</sam:orderNo> 3 <sam:item> 4 <sam:id>ITEM003</sam:id> 5 <sam:description>Latest Item</sam:description> 6 <sam:size>Large</sam:size> 7 </sam:item> 8 <sam:address> 9 <sam:Name>BEA Systems, Inc</sam:Name> 10 <sam:Street>10230 NE Points Drive, Ste 300</sam:Street> 11 <sam:City>Kirkland</sam:City> 12 <sam:Zip>98033</sam:Zip> 13 <sam:State>WA</sam:State> 14 <sam:Country>USA</sam:Country> 15 </sam:address> 16 <sam:quantity>4</sam:quantity> 17 </sam:order>
This is a valid instance document. When a schema is compiled, the API generated from the schema is integrated with the XMLBeans type system that represents the underlying XML schema. Access to schema-related information can be obtained using the schema type system API.
In the next sample, we show how to programmatically access the various enumeration values for a certain schema type using the
getEnumerationValues() method. The schema type we are using is
sizeType, which is an enumeration with three possible values. The schema snippet is listed below:
1 <xs:simpleType name="sizeType"> 2 <xs:restriction base="xs:token"> 3 <xs:enumeration value="Small"/> 4 <xs:enumeration value="Medium"/> 5 <xs:enumeration value="Large"/> 6 </xs:restriction> 7 </xs:simpleType>
SizeType is the
SchemaType class containing information regarding the
simpleType schema type:
SchemaType schType = null; XmlAnySimpleType  xmlarray = null; SizeType sType = SizeType.Factory.newInstance(); schType = sType.schemaType(); xmlarray = schType.getEnumerationValues();
Running this code sample (EnumerationSample.java) will result in the enumeration values being programmatically obtained and redirected to System.out:
Enumeration values for ItemType : Small Medium Large
XmlCursors are an interesting feature in XMLBeans; they provide an intuitive way to manipulate or navigate an XML instance document. XmlCursors also give you a way to execute XQuery expressions. Once you load an XML document, you can create a cursor to represent a specific place in the XML. Because you can use a cursor with or without a schema corresponding to the XML, cursors are an ideal way to handle XML.
The next sample demonstrates the use of a cursor to manipulate an XMLBean instance. This sample parses the
sample.xml created in the first sample. Once the file is in memory, the XmlCursor API is used to navigate to the quantity element and change the value to 104:
orderDoc = OrderDocument.Factory.parse(new File("sample.xml")); XmlCursor xcursor = orderDoc.newCursor(); xcursor.toFirstChild(); xcursor.toChild(3); xcursor.toEndToken(); xcursor.toPrevChar(1); xcursor.insertChars("10"); xcursor.dispose();
Running this sample generates the following output that displays the reason why the modified XMLBean document isn't valid:
Message: decimal value (104) is greater than maxInclusive facet (5) for quantityType in namespace http://temp.openuri.org/Sample Location of invalid XML: <xml-fragment xmlns:sam="http://temp.openuri.org/Sample"/>
Now that we've taken a brief look at XMLBeans, let's look at what's new in version 2.0.