Home > Code, Java > Using JAXB to generate Java Objects from XML document

Using JAXB to generate Java Objects from XML document

Quite sometime back I had written about Using JAXB to generate XML from the Java, XSD. And now I am writing how to do the reverse of it i.e generating Java objects from the XML document. There was one comment mentioning that JAXB reference implementation and hence in this article I am making use of the reference implementation that is shipped with the JDK.

Firstly the XML which I am using to generate the java objects are:

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

<expenseReport>
  <user>
    <userName>Sanaulla</userName>
  </user>
  <items>
    <item>
      <itemName>Seagate External HDD</itemName>
      <purchasedOn>August 24, 2010</purchasedOn>
      <amount>6776.5</amount>
    </item>
    <item>
      <itemName>Benq HD Monitor</itemName>
      <purchasedOn>August 24, 2012</purchasedOn>
      <amount>15000</amount>
    </item>
  </items>
</expenseReport>

And the XSD to which it confirms to is:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="expenseReport" type="ExpenseT" />
  <xs:complexType name="ExpenseT">
    <xs:sequence>
      <xs:element name="user" type="UserT" />
      <xs:element name="items" type="ItemListT" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="UserT">
    <xs:sequence>
      <xs:element name="userName" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ItemListT">
    <xs:sequence>
      <xs:element name="item" type="ItemT" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ItemT">
    <xs:sequence>
      <xs:element name="itemName" type="xs:string" />
      <xs:element name="purchasedOn" type="xs:string" />
      <xs:element name="amount" type="xs:decimal" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

The XSD has already been explained and one can find out more by reading this article.

I create a class: XmlToJavaObjects which will drive the unmarshalling operation and before I generate the JAXB Classes from the XSD, the directory structure is:
DirStruct

I go ahead and use the xjc.exe to generate JAXB classes for the given XSD:

$> xjc expense.xsd

which gives me:
XJCOut

and I now refresh the directory structure to see these generated classes as shown below:
DirStruct2
With the JAXB Classes generated and the XML data available, we can go ahead with the Unmarshalling process.

Unmarshalling the XML:

To unmarshall:

  1. We need to create JAXContext instance.
  2. Use JAXBContext instance to create the Unmarshaller.
  3. Use the Unmarshaller to unmarshal the XML document to get an instance of JAXBElement.
  4. Get the instance of the required JAXB Root Class from the JAXBElement.

Once we get the instance of the required JAXB Root class, we can use it to get the complete XML data in Java objects. The code to unmarshal the XML data is given below:

package problem;

import generated.ExpenseT;
import generated.ItemListT;
import generated.ItemT;
import generated.ObjectFactory;
import generated.UserT;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class XmlToJavaObjects {

  /**
   * @param args
   * @throws JAXBException 
   */
  public static void main(String[] args) throws JAXBException {
    //1. We need to create JAXContext instance
    JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
    
    //2. Use JAXBContext instance to create the Unmarshaller.
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

    //3. Use the Unmarshaller to unmarshal the XML document to get an instance of JAXBElement.
    JAXBElement<ExpenseT> unmarshalledObject = 
        (JAXBElement<ExpenseT>)unmarshaller.unmarshal(
            ClassLoader.getSystemResourceAsStream("problem/expense.xml"));

    //4. Get the instance of the required JAXB Root Class from the JAXBElement.
    ExpenseT expenseObj = unmarshalledObject.getValue();
    UserT user = expenseObj.getUser();
    ItemListT items = expenseObj.getItems();

    //Obtaining all the required data from the JAXB Root class instance.
    System.out.println("Printing the Expense for: "+user.getUserName());
    for ( ItemT item : items.getItem()){
      System.out.println("Name: "+item.getItemName());
      System.out.println("Value: "+item.getAmount());
      System.out.println("Date of Purchase: "+item.getPurchasedOn());
    }   
  }

}

And the output would be:
Output

Do drop in your queries/feedback as comments and I will try to address them at the earliest.

Categories: Code, Java Tags: , ,
  1. Letty
    March 21st, 2013 at 05:06 | #1

    Did you create your XSD by hand? Is there a way to automate the XSD from XML?

    • March 21st, 2013 at 13:10 | #2

      I dont think there’s a way to automate XSD from XML and if there is one I am not aware of it. In Eclipse there is an option to generate XML from XSD.

      • Mohit Jain
        December 16th, 2014 at 14:36 | #3

        To create XSD from Xml we can use Trang.jar. Its open source executable jar.

  2. Letty
    March 22nd, 2013 at 21:11 | #4

    So in your example above, did you generate your XSD manually by hand? I guess I am trying to find a process for generating both the XML and XSD items.

    • March 22nd, 2013 at 21:16 | #5

      I had created the XSD first and had used it to generate the XML using JAXB. I then used the same XSD. I am not aware of any tool to generate the XSD. But there should be tool (atleast Eclipse IDE has it) which would use the XSD to generate a sample XML which confirms to the XSD.
      If you dont have both XML and XSD then I think its difficult to generate both XML and XSD.

      • Letty
        March 22nd, 2013 at 23:37 | #6

        Okay. I see what you are saying. I did not want to learn XSD syntax but I see I will need to. There are tools out there that generated XSD from XML like Altova XML Spy but it doesn’t help for JAXB. Thanks for your help. Very helpful. :)

      • April 6th, 2013 at 05:29 | #7

        There are fairly easy ways to create XSDs automatically from existing XMLs. However: some attributes falsely contain the “optional”-attribute as well as have a wrong max-/minOccurs set. Other than that they work just fine. I’m sure there are tools, that can do it, but I myself used this site and went through the result checking it: http://www.freeformatter.com/xsd-generator.html imo it worked well. Not sure whether I’ll use JAXB at all, but thanks for this little tutorial :).

  3. prashansa
    April 5th, 2013 at 15:45 | #8

    I have a problem. I am taking data from jsp form.and creating xml using jaxb.it’s ok it’s creating xml file but when i inserting detail from jsp form second time all the detail is going to overwrite.but I want to keep all the detail in xml not to overwright.
    please reply
    thanks in advance

  4. paragflume
    October 3rd, 2013 at 21:33 | #9

    How to customize the package name or info of the generated classes

  1. January 25th, 2013 at 17:26 | #1