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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<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

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// 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 <code>set</code> 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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// 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
6 years ago

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

Ansari
Ansari
5 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