JAXB: Generate Classes from XSD
In this tutorial, we shall learn generating classes from XML Schema Design (XSD) using JAXB. This can be achieved using JAXB binding compiler XJC
command. XJC
is included in the bin directory in the JDK starting with Java SE 6.
1. Requirements
To see this example in action, following is the minimum requirement:
- JDK 6 (Java SE 6) or later
- JAXB 2.1 API
2. XJC command
The JAXB XJC
schema binding compiler transforms/binds, a source XML schema (XSD) to a set of JAXB content classes in the Java programming language.
To see the usage of XJC
command, just type in the same in command prompt/shell:
3. XJC in Action: Generating classes form XSD
To see the command XJC
in action, we will need an XSD file. We will be using following XSD file in our example.
Employee.xsd
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="employee"> <xs:complexType> <xs:sequence> <xs:element type="xs:byte" name="id"/> <xs:element type="xs:string" name="name"/> <xs:element name="address"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="addressLine1"/> <xs:element type="xs:string" name="addressLine2"/> <xs:element type="xs:string" name="country"/> <xs:element type="xs:string" name="state"/> <xs:element type="xs:short" name="zip"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element type="xs:string" name="assestsAllocated" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
To run the command, we shall browse to the directory having the xsd file, and then we shall execute following command:
xjc -d src -p com.javacodegeeks.examples.xjc Employee.xsd
Here -d
specifies to which folder generated classes shall go. In this case it shall be src directory, make sure that the target directory exists. -p
specifies the target package structure. In this case it would be com.javacodegeeks.examples.xjc
Following shall be the output of above command:
And we can see the package structure is created in the desired manner:
Now let us see the java files created.
Employee.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2016.02.28 at 03:27:10 PM IST
//
package com;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="address">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="addressLine1" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="addressLine2" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="country" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="state" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="zip" type="{http://www.w3.org/2001/XMLSchema}short"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* <element name="assestsAllocated" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
* <element name="id" type="{http://www.w3.org/2001/XMLSchema}byte"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"name",
"address",
"assestsAllocated",
"id"
})
@XmlRootElement(name = "employee")
public class Employee {
@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected Employee.Address address;
protected List assestsAllocated;
protected byte id;
/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the address property.
*
* @return
* possible object is
* {@link Employee.Address }
*
*/
public Employee.Address getAddress() {
return address;
}
/**
* Sets the value of the address property.
*
* @param value
* allowed object is
* {@link Employee.Address }
*
*/
public void setAddress(Employee.Address value) {
this.address = value;
}
/**
* Gets the value of the assestsAllocated property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a set
method for the assestsAllocated property.
*
* <p>
* For example, to add a new item, do as follows:
* getAssestsAllocated().add(newItem);
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List getAssestsAllocated() {
if (assestsAllocated == null) {
assestsAllocated = new ArrayList();
}
return this.assestsAllocated;
}
/**
* Gets the value of the id property.
*
*/
public byte getId() {
return id;
}
/**
* Sets the value of the id property.
*
*/
public void setId(byte value) {
this.id = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="addressLine1" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="addressLine2" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="country" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="state" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="zip" type="{http://www.w3.org/2001/XMLSchema}short"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"addressLine1",
"addressLine2",
"country",
"state",
"zip"
})
public static class Address {
@XmlElement(required = true)
protected String addressLine1;
@XmlElement(required = true)
protected String addressLine2;
@XmlElement(required = true)
protected String country;
@XmlElement(required = true)
protected String state;
protected short zip;
/**
* Gets the value of the addressLine1 property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getAddressLine1() {
return addressLine1;
}
/**
* Sets the value of the addressLine1 property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setAddressLine1(String value) {
this.addressLine1 = value;
}
/**
* Gets the value of the addressLine2 property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getAddressLine2() {
return addressLine2;
}
/**
* Sets the value of the addressLine2 property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setAddressLine2(String value) {
this.addressLine2 = value;
}
/**
* Gets the value of the country property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCountry() {
return country;
}
/**
* Sets the value of the country property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCountry(String value) {
this.country = value;
}
/**
* Gets the value of the state property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getState() {
return state;
}
/**
* Sets the value of the state property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setState(String value) {
this.state = value;
}
/**
* Gets the value of the zip property.
*
*/
public short getZip() {
return zip;
}
/**
* Sets the value of the zip property.
*
*/
public void setZip(short value) {
this.zip = value;
}
}
}
We can see that Employee.java also has static class Address
as it was desired.
Also we can see that an unexpected ObjectFactory.java is also created. This contains factory methods to create objects of classes created. This can come into use when creating JAXBElement representation of objects.
ObjectFactory.java
// // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 // 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: 2016.02.27 at 09:09:47 PM IST // package com.javacodegeeks.examples.xjc; import javax.xml.bind.annotation.XmlRegistry; /** * This object contains factory methods for each * Java content interface and Java element interface * generated in the com.javacodegeeks.examples.xjc package. * <p>An ObjectFactory allows you to programatically * construct new instances of the Java representation * for XML content. The Java representation of XML * content can consist of schema derived interfaces * and classes representing the binding of schema * type definitions, element declarations and model * groups. Factory methods for each of these are * provided in this class. * */ @XmlRegistry public class ObjectFactory { /** * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.javacodegeeks.examples.xjc * */ public ObjectFactory() { } /** * Create an instance of {@link Employee } * */ public Employee createEmployee() { return new Employee(); } /** * Create an instance of {@link Employee.Address } * */ public Employee.Address createEmployeeAddress() { return new Employee.Address(); } }
4. Conclusion
In this example, we learnt what is XJC
, how to generate binding Java classes from an XSD, and the sample code generated. The code generated was the desired class type and the object factory that can be used to create objects of the generated class.
Did you try on Java 8? For me it works on 6, and 7, but not 8 or greater.
Even for me its not working on Java 8, I tired its say Xjc is not recognozied.