Sunday, August 17, 2014

JAXB Generating Java Classes From XML

Let's generate the Java classes using xjc compile. xjc tool is lying in the bin folder of download from [http://example.com|https://jaxb.dev.java.net]. The schema that we use for generating the class file is

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<xsd:schema targetNamespace="http://www.lalit.com/om"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:om="http://www.lalit.com/om"
    xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.w3.org/2001/XMLSchema-instance
                            http://www.w3.org/2001/XMLSchema-instance.xsd
                            http://www.w3.org/2001/XMLSchema
                             http://www.w3.org/2001/XMLSchema.xsd">

        <xsd:element name="user" type="om:UserType" />
    
    <xsd:complexType name="UserType">
        <xsd:sequence>
            <xsd:element name="homeAddress" type="om:Address" />
            <xsd:element name="officeAddress" type="om:Address" />
            <xsd:element name="comment" type="string" />
            <xsd:element name="productBought" type="om:Products" />
        </xsd:sequence>
        <xsd:attribute name="startDate" type="xsd:date" />
    </xsd:complexType>

    <xsd:complexType name="Address">
        <xsd:sequence>
            <xsd:element name="houseNo" type="xsd:string" />
            <xsd:element name="society" type="xsd:string" />
            <xsd:element name="locality" type="xsd:string" />
            <xsd:element name="city" type="xsd:string" />
            <xsd:element name="pin" type="xsd:decimal" />
        </xsd:sequence>
        <xsd:attribute name="country" default="India">
        </xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="Products">
       <xsd:sequence>
        <xsd:element name="product" minOccurs="0" maxOccurs="unbounded">
               <xsd:complexType>
              <xsd:sequence>
            <xsd:element name="name" type="xsd:string" />
            <xsd:element name="quantity" type="xsd:integer" />
            <xsd:element name="price" type="xsd:decimal" />
            <xsd:element name="purchaseDate" type="xsd:date" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="productNo" type="string" use="required" />
            </xsd:complexType>
        </xsd:element>
       </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Run the compiler as shown below:

xjc -d <folder where the classes to be generated> <location of xsd file>

It will generate classes using the package structure as reflected by the target namespace of the xsd file. Once the classes are generated you will see the generated java classes having annotations. Let's look into the 

UserType.java class

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-792
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2009.04.02 at 03:42:03 PM IST
//

package com.lalit.om;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;

/**
 * <p>Java class for UserType complex type.
 *
 * <p>The following schema fragment specifies the expected content contained within this class.
 *
 * <pre>
 * &lt;complexType name="UserType">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="homeAddress" type="{http://www.lalit.com/om}Address"/>
 *         &lt;element name="officeAddress" type="{http://www.lalit.com/om}Address"/>
 *         &lt;element name="comment" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         &lt;element name="productBought" type="{http://www.lalit.com/om}Products"/>
 *       &lt;/sequence>
 *       &lt;attribute name="startDate" type="{http://www.w3.org/2001/XMLSchema}date" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UserType", propOrder = {
    "homeAddress",
    "officeAddress",
    "comment",
    "productBought"
})
public class UserType {

    @XmlElement(required = true)
    protected Address homeAddress;
    @XmlElement(required = true)
    protected Address officeAddress;
    @XmlElement(required = true)
    protected String comment;
    @XmlElement(required = true)
    protected Products productBought;
    @XmlAttribute
    @XmlSchemaType(name = "date")
    protected XMLGregorianCalendar startDate;

//Getter and setters not shown here

The java class has annotations which are self explanatory. The details are cover elsewhere. Now any XML file conforming to the above XSD can be read using JAXB api.

The following code is used to read the XML:

//Get the JAXB Context~~
JAXBContext jc = JAXBContext.newInstance("com.lalit.om");
Unmarshaller unmarshaller = jc.createUnmarshaller();

//Enable the validation handler~~
unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());

//Get the root and do processing in OO way~~            
JAXBElement<UserType> userType =
   (JAXBElement<UserType>)unmarshaller.unmarshal(new File("src/user_jaxb.xml"));
UserType user = (UserType)userType.getValue();
System.out.println(user.getProductBought().getProduct().size());

To generate the XML back using the marshaller is as follows

//Generating the XML file using the generated code~~
//At the moment we will use the generated user object.~~
ObjectFactory of =  new ObjectFactory();
JAXBElement jce = of.createUser(user);
JAXBContext jcc = JAXBContext.newInstance("com.lalit.om");
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal( jce, System.out );

The above code will generate the XML in the System.out console.

More on JAXB

No comments:

Post a Comment