bind

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:

  1. JDK 6 (Java SE 6) or later
  2. 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:

XJC Command Usage
XJC Command Usage

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:

XJC Execution
XJC Execution

And we can see the package structure is created in the desired manner:

Package Structure
Package Structure

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.

Saurabh Arora

Saurabh graduated with an engineering degree in Information Technology from YMCA Institute of Engineering, India. He is SCJP, OCWCD certified and currently working as Technical Lead with one of the biggest service based firms and is involved in projects extensively using Java and JEE technologies. He has worked in E-Commerce, Banking and Telecom domain.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
David
David
5 years ago

Did you try on Java 8? For me it works on 6, and 7, but not 8 or greater.

Ansari
Ansari
4 years ago
Reply to  David

Even for me its not working on Java 8, I tired its say Xjc is not recognozied.

Back to top button