Friday, July 29, 2011

Transform Object into XML using JAXB

In the last post we had seen how to transform XML data into user presentable HTML format. What if you don't have data in XML format? What if the data is collected from a legacy system or from a collection of services?

Here we are going to look at how to transform the Java object to XML and this XML can be presented in any format we want.

Like JAXP, Java comes to rescue us here with JAXB (Java Architecture for XML Binding). All we need is an XSD which defines the structure of the Java Object and the XML.

JAXB allows us to transform data in both the direction, means, you can convert Object to XML and XML to Object.
Wow, what are we then waiting for? Let's program.

Open Netbeans and create a Java Application
  • File->New Project->Java Application
  • Enter "XMLBinding" in the Project Name field
  • Click Finish
Create an XSD file
  • Open Projects tab
  • Right click xmlbinding package node
  • Choose XML-> XML Schema
  • Enter "student-marks" as the file name
  • Click Finish
Copy and paste the following content in the XSD file's editor.
<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://xml.netbeans.org/schema/student-marks"
    xmlns:tns="http://xml.netbeans.org/schema/student-marks"
    elementFormDefault="qualified">
  <xsd:element name="report">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="students">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="student" maxOccurs="unbounded">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="name">
                      <xsd:simpleType>
                        <xsd:restriction base="xsd:string"/>
                      </xsd:simpleType>
                    </xsd:element>
                    <xsd:element name="marks">
                      <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="maths" type="xsd:int"/>
                          <xsd:element name="physics" type="xsd:int"/>
                          <xsd:element name="chemistry" type="xsd:int"/>
                          <xsd:element name="biology" type="xsd:int"/>
                        </xsd:sequence>
                      </xsd:complexType>
                    </xsd:element>
                  </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Now we are going to create XML-Java binding.
  • Right click on the project node
  • New->JAXB binding
  • Enter "Students" in binding name in field
  • Select the xsd file
  • Enter "xmlbinding.resource" in package field
  • Click Finish

Your project folder structure will look like this.



Edit the XMLBinding.java and replace its content with the following.

package xmlbinding;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import xmlbinding.resource.ObjectFactory;
import xmlbinding.resource.Report;
import xmlbinding.resource.Report.Students;
import xmlbinding.resource.Report.Students.Student;
import xmlbinding.resource.Report.Students.Student.Marks;

/**
 * This class binds xml with a java object and facilitates smooth data conversion
 * from either side.
 * @author Pragalathan M
 */
public class XMLBinding {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws JAXBException {
        ObjectFactory factory = new ObjectFactory();
        Report report = factory.createReport();
        Students students = factory.createReportStudents();
        Student student = factory.createReportStudentsStudent();
        student.setName("Lydia");
        Marks marks = factory.createReportStudentsStudentMarks();
        marks.setMaths(100);
        marks.setPhysics(98);
        marks.setChemistry(85);
        marks.setBiology(93);
        student.setMarks(marks);
        students.getStudent().add(student);

        student = factory.createReportStudentsStudent();
        student.setName("Angel");
        marks = factory.createReportStudentsStudentMarks();
        marks.setMaths(100);
        marks.setPhysics(88);
        marks.setChemistry(95);
        marks.setBiology(94);
        student.setMarks(marks);
        students.getStudent().add(student);
        
        report.setStudents(students);

        JAXBContext jaxbContext = JAXBContext.newInstance("xmlbinding.resource");
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(report, System.out);
    }
}

Hurrah... here is the output.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<report xmlns="http://xml.netbeans.org/schema/student-marks">
    <students>
        <student>
            <name>Lydia</name>
            <marks>
                <maths>100</maths>
                <physics>98</physics>
                <chemistry>85</chemistry>
                <biology>93</biology>
            </marks>
        </student>
        <student>
            <name>Angel</name>
            <marks>
                <maths>100</maths>
                <physics>88</physics>
                <chemistry>95</chemistry>
                <biology>94</biology>
            </marks>
        </student>
    </students>
</report>

We will see how to convert XML to Java object in the next post.