Praveen Singh

XML Binding in JAVA: apache XMLBeans vs JaxB

Popularity of XML is growing day by day, even birth of new portable text technology like JSON, not stopping XML to grow.

Reason behind this not XML alone but other technology which revolved around it like XSD, XSLT etc.

Almost every other language comes up with support of XML.

Java is seems ahead of any other language with different type of parsers (DOM, SAX, STAX, TRAX, etc), XML based framework (apache Cocoon, etc).

But here we are not going to talk about parsers, we are going to discuss about XML Binding in JAVA.

Q. I heard about parsing but what is XML Binding?

A. XML Binding is the way by which we bind JAVA class with XML and we can read every part of xml using just getter – setter methods of POJO.

We can convert XML to POJO and POJO to XML back.

Below diagram will explain how its work.



Q. I am very much comfortable in XML parsing, why would I go for XML binding?

A . Let's discuss what a JAVA developer do when they actually "parse" the XML. They read XML, part by part and create a object which most of the time represents XML only one way or other.

XML Binding will just eliminate the developers code of reading the XML and return you simple java objects represents the XML.

Q. Hey, most of the time what I need is just the small section of XML, say 5% to 10% of whole xml. Why should I create the Object corresponding to whole XML and waste system memory?

A. yes you are correct, XML Binding is not a good in this situation !

Q .Ok let's start, but tell me first what i will be needed ?

A . Prerequisites are following

  • Basic knowledge of XML and XSD.
  • JDK 6.
  • Java IDE(I recommend Eclipse Galileo ).

Q. Ok let's start !

A . In this article my aim is to highlight how we can convert XML-POJO-XML, I might discuss other part of tool/library.

According to me best way to represent a XMl is by XSD only

Currently most widely used XML Binding framework, which use XSD to create POJO are apache XMLBeans and JAXB.

We are going to cover how we use them, pros and cons etc

Q. What if I am not interested in XML binding by XSD ?

A. You can try XStream for that , very simple library to do XML Binding and provide JSON support also

You can check my blog article : XStream : Make XML Binding easy !

Q .Continue!

Ok let's start with JAXB and XMLBeans

Since both uses XML Schema to bind with xml, lets first decide the xsd, in this article I used this xsd

xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

targetNamespace="http://www.nokia.com/beans/Employee"

xmlns:tns="http://www.nokia.com/beans/Employee"

elementFormDefault="qualified">

<xs:element name="employee">

<xs:complexType>

<xs:sequence>

<xs:element name="empId" type="xs:int" />

<xs:element name="name">

<xs:complexType>

<xs:sequence>

<xs:element name="firstName" type="xs:string"

minOccurs="1" maxOccurs="1" />

<xs:element name="lastName" type="xs:string"

minOccurs="1" maxOccurs="1" />

xs:sequence>

xs:complexType>

xs:element>

<xs:element name="dateOfBirth" type="xs:date" />

<xs:element name="address">

<xs:complexType>

<xs:sequence>

<xs:element name="houseNo" type="xs:string" />

<xs:element name="addressLine1" type="xs:string" />

<xs:element name="addressLine2" type="xs:string" />

<xs:element name="zipCode" type="xs:int" minOccurs="1" />

xs:sequence>

xs:complexType>

xs:element>

<xs:element name="qualification" minOccurs="1" maxOccurs="unbounded">

<xs:complexType>

<xs:attribute name="name" type="xs:string" />

<xs:attribute name="detail" type="xs:string" />

xs:complexType>

xs:element>

xs:sequence>

xs:complexType>

xs:element>

xs:schema>


Q. Why this XSD ?

A . Their list of thing which I want to check

· Like mandatory fields if I do minOccurs="1" maxOccurs="1".

· Xs:date.

· List of elements, when I do minOccurs="1" maxOccurs="unbounded".

· Attributes, when I use <xs:attribute/>.

Q. Ok, continue!

So above XSD can result to XML like this

xml version="1.0" encoding="UTF-8" standalone="yes"?>

<employee xmlns="http://www.nokia.com/beans/Employee">

<empId>1214empId>

<name>

<firstName>PraveenfirstName>

<lastName>Kumar SinghlastName>

name>

<dateOfBirth>2010-04-01+05:30dateOfBirth>

<address>

<houseNo>4GhouseNo>

<addressLine1>Tulip ApartmentaddressLine1>

<addressLine2>BangaloreaddressLine2>

<zipCode>456456zipCode>

address>

<qualification detail="BTEch in ECE" name="BTech"/>

<qualification detail="MTech in CSE" name="MTech"/>

employee>


How we get in apache XMLBean.

Resulting POJO can be different depending on the library we are using.

One of the goals of this article is to find out how easy to get them

Ok Before Jumping to the code, let's see how we get POJO from xsd

download the binaries of XMLBeans from apache website and extract in your system.

I am using xmlbeans-2.5.0 and I am dumping it to C:\Frameworks

Now how you create POJOs depend on you, you can directly create it from console or you can use ant for this

I am using console way, in windows XP

On cmd, try to go in C:\Frameworks\xmlbeans-2.5.0\bin folder

Then write scomp -out c:\xmlBean\xsdJar\Employee.jar c:\xmlBean\xsd\Employee.xsd

Now assuming it you have xsd on location C:\xmlBean\xsd above syntax will dump Employee.jar in c:\xmlBean\xsdJar\


NOTE : To avoid going in C:\Frameworks\xmlbeans-2.5.0\bin folder you can set the location of XMLBean binaries in Environment variable


Now few point to notice

  • You will not get the .java file but jars with tons of classes inside.
  • Apache XMLBeans uses factory patterns to create these set of classes, if you are comfortable with them, yes, go inside and check the code otherwise forget about them.

Now use this jars and dump in your project with other library jars, final jars structure will look like






How we get in JAXB.

Open cmd and type

xjc c:\jaxB\src\xsd\Employee.xsd -d c:\jaxB\src

now if you have xsd at :\jaxB\src\xsd\ you will get set of .java file at c:\jaxB\src

For our xsd we will get

  1. Employee.java
  2. ObjectFactory.java
  3. package-info.java

Dump in your project, package structure inspired by namespace you have mention in XSD.

Now let's start the code, please go thru the comments to understand the code

How we use apache XMLBeans.


import java.util.Calendar;

import java.util.Date;

import org.apache.xmlbeans.XmlException;

import org.example.employee.EmployeeDocument;

import org.example.employee.EmployeeDocument.Employee;

import org.example.employee.EmployeeDocument.Employee.Address;

import org.example.employee.EmployeeDocument.Employee.Name;

import org.example.employee.EmployeeDocument.Employee.Qualification;

/**

* @author Praveen K Singh

*

*/

public class TestXmlBean {

public static void main(String[] args) throws XmlException {

/*

* Create EmployeeDocument using its factory, which will provide you

* root of XML and set all the details.

*/

EmployeeDocument employeeDoc = EmployeeDocument.Factory.newInstance();

Employee employee = employeeDoc.addNewEmployee();

employee.setEmpId(1214);

Name name = employee.addNewName();

name.setFirstName("Praveen");

name.setLastName("k Singh");

Calendar cal = Calendar.getInstance();

cal.setTime(new Date());

employee.setDateOfBirth(cal);

Address address = employee.addNewAddress();

address.setHouseNo("4G");

address.setAddressLine1("Tulip apartment");

address.setAddressLine2("Outer Ring Road");

address.setZipCode(111111);

Qualification[] qualifications = new Qualification[2];

Qualification qualification = Qualification.Factory.newInstance();

qualification.setName("BTech");

qualification.setDetail("In ECE");

qualifications[0] = qualification;

qualification = Qualification.Factory.newInstance();

qualification.setName("MTech");

qualification.setDetail("In CSE");

qualifications[1] = qualification;

employee.setQualificationArray(qualifications);

/*

* Check the POJO matches with the XSD or not, we will discuss more about this.

*/

System.out.println(employeeDoc.validate());

/*

* Print XML on Console.

* Doing POJO to XML

*/

System.out.println(employeeDoc.toString());

/*

* Geting XML data and creating POJO from them.

* Doing XML to POJO.

*/

EmployeeDocument employeeDoc1 = EmployeeDocument.Factory

.parse(employeeDoc.toString());

System.out.println(employeeDoc1);

}

}

How we use JaxB



import java.io.File;

import java.util.GregorianCalendar;

import java.util.List;


import javax.xml.XMLConstants;

import javax.xml.bind.JAXBContext;

import javax.xml.bind.JAXBException;

import javax.xml.bind.Marshaller;

import javax.xml.bind.Unmarshaller;

import javax.xml.datatype.DatatypeConfigurationException;

import javax.xml.datatype.DatatypeFactory;

import javax.xml.datatype.XMLGregorianCalendar;

import javax.xml.validation.Schema;

import javax.xml.validation.SchemaFactory;


import org.xml.sax.SAXException;


import com.nokia.beans.employee.Employee;

import com.nokia.beans.employee.Employee.Address;

import com.nokia.beans.employee.Employee.Name;

import com.nokia.beans.employee.Employee.Qualification;


/**

* @author
Praveen K Singh

*

*/

public
class TestJaxB {


public
static
void main(String[] args) throws JAXBException,

DatatypeConfigurationException, SAXException {

/*

* Create instance of Employee class as per your needs.

*/

Employee employee = new Employee();

employee.setEmpId(1214);

Name name = new Name();

name.setFirstName("Praveen");

name.setLastName("Kumar Singh");

employee.setName(name);

GregorianCalendar gcal = new GregorianCalendar();

gcal.set(2010, 03, 1);

XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()

.newXMLGregorianCalendar(gcal);

employee.setDateOfBirth(xgcal);

Address address = new Address();

address.setHouseNo("4G");

address.setAddressLine1("Tulip Apartment");

address.setAddressLine2("Bangalore");

address.setZipCode(456456);

employee.setAddress(address);

List<Employee.Qualification> qualificationList = employee

.getQualification();

Qualification qualification = new Qualification();

qualification.setName("BTech");

qualification.setDetail("BTEch in ECE");

qualificationList.add(qualification);

qualification = new Qualification();

qualification.setName("MTech");

qualification.setDetail("MTech in CSE");

qualificationList.add(qualification);

/*

* Below code will help in validation with schema.

*/

SchemaFactory schemaFactory = SchemaFactory

.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

Schema schema = schemaFactory.newSchema(new File(

"C:/jaxB/src/xsd/Employee.xsd"));

JAXBContext jaxbContext = JAXBContext

.newInstance("com.nokia.beans.employee");

Marshaller marshaller = jaxbContext.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.setSchema(schema);

/*

* Convert Employee instance to XML as per XSD. Doing POJO to XML.

*/

marshaller.marshal(employee, System.out);

File file = new File("c:/employee.xml");

marshaller.marshal(employee, file);

Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

unmarshaller.setSchema(schema);

/*

* Converts XML to OBject. Doinf POJO to XML.

*/

Object obj = unmarshaller.unmarshal(file);

System.out.println((Employee) obj);

}

}



As you can see Both libraries provide very simple mechanism to bind XML with JAVA Objects.

But yes we have some differences, lets concentrate on that


Advantages of apache XMLBean

  • Provide you a single .jar file equivalent to xsd.
  • Once jar is ready, no need to xsd any more, even for validation.
  • Very simple way of XSD validation, return true or false.
  • Discourage modification in classes generated, hence less chances of bug.
  • Easy to set date and time.
  • provide method which can except xml as String also provide xml as string, this what you want most of the time In a java application.
  • Bit old, provide good online support.
  • Provide built in mechanism to handle XML like XQuery and XPath.


Advantages of apache JAXB

  • Provide simple pojo class which is easy to understand and use.
  • Easy to update and modify as its provide .java classes.
  • No jars needed, provided by JDK 6.
  • Almost standard in java community as it's specification is provided by sun java.


Disadvantages of apache XMLBean

  • Factory pattern, difficult to understand.
  • Tons of classes inside jar, nightmare for developer if he/she want to modify jar for some reasons.
  • Inbuilt toString() is bit confusing as it return XML representation of POJO.
  • No support of JSON Conversion.


Disadvantages of apache JAXB

  • No toString() method.
  • Use inner classes, bit difficult to understand and modify.
  • Long and lengthy way of schema validation, even you need .xsd file for that.
  • No method which take xml as String and provide xml as String, directly.
  • No support of JSON Conversion.

Summary

Both have their pros and cons and can be used as per projects need and developers understanding. JSON support is something which is missing in both. But as time passes JaxB slowly becoming standard.


No comments:

Post a Comment