For elements with max occurs greater than one, JAXB will generate a j
ava.util.List property and the underlying implementation will be
java.util.ArrayList. You can control which list implementation is used through internal and external schema annotations. You can also use your own domain objects which gives you full control of your object model. This post will discuss these different options.
Option #1 - Default JAXB Generation
We will use the following XML schema for this post:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
xsd:schema
<
xsd:element
name
=
"customer"
>
<
xsd:complexType
>
<
xsd:sequence
>
<
xsd:element
name
=
"phone-number"
type
=
"xsd:string"
maxOccurs
=
"unbounded"
/>
</
xsd:sequence
>
</
xsd:complexType
>
</
xsd:element
>
</
xsd:schema
>
|
Using the following command line:
1
|
xjc -d out customer.xsd
|
JAXB will generate the following class. This class has a
java.util.List property with
java.util.ArrayList as the underlying implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package
generated;
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;
@XmlAccessorType
(XmlAccessType.FIELD)
@XmlType
(name =
""
, propOrder = {
"phoneNumber"
})
@XmlRootElement
(name =
"customer"
)
public
class
Customer {
@XmlElement
(name =
"phone-number"
, required =
true
)
protected
List<String> phoneNumber;
public
List<STRING> getPhoneNumber() {
if
(phoneNumber ==
null
) {
phoneNumber =
new
ArrayList<String>();
}
return
this
.phoneNumber;
}
}
</STRING>
|
Option #2 - Customizing the Generation
If you wish to control the underlying implementation you can use an external binding file. We will use the bindings file below to change the underlying implementation to be
java.util.LinkedList:
1
2
3
4
5
6
7
8
9
10
11
12
|
<
jxb:bindings
version
=
"2.1"
>
<
jxb:bindings
schemaLocation
=
"customer.xsd"
>
<
jxb:bindings
node
=
"//xs:element[@name='customer']/xs:complexType/xs:sequence/xs:element[@name='phone-number']"
>
<
jxb:property
collectionType
=
"java.util.LinkedList"
/>
</
jxb:bindings
>
</
jxb:bindings
>
</
jxb:bindings
>
|
And the following XJC call:
1
|
xjc -d out -b binding.xml customer.xsd
|
To get the following class instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package
generated;
import
java.util.LinkedList;
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;
@XmlAccessorType
(XmlAccessType.FIELD)
@XmlType
(name =
""
, propOrder = {
"phoneNumber"
})
@XmlRootElement
(name =
"customer"
)
public
class
Customer {
@XmlElement
(name =
"phone-number"
, required =
true
)
protected
List<STRING> phoneNumber =
new
LinkedList<STRING>();
public
List<STRING> getPhoneNumber() {
if
(phoneNumber ==
null
) {
phoneNumber =
new
LinkedList<STRING>();
}
return
this
.phoneNumber;
}
}
</STRING></STRING></STRING></STRING>
|
Option #3 - Using Your Own Domain Class
Generally you should interact with the java.util.List interface whenever possible. However in your own domain classes you are free to make your properties any of the java.util.List implementations you wish (perhaps to make use of calls like
java.util.ArrayList.trimToSize()).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package
com.example;
import
java.util.ArrayList;
import
javax.xml.bind.annotation.XmlAccessType;
import
javax.xml.bind.annotation.XmlAccessorType;
import
javax.xml.bind.annotation.XmlElement;
import
javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType
(XmlAccessType.FIELD)
@XmlRootElement
(name =
"customer"
)
public
class
Customer {
@XmlElement
(name =
"phone-number"
, required =
true
)
protected
ArrayList<STRING> phoneNumber;
public
Customer() {
phoneNumber =
new
ArrayList<STRING>();
}
public
ArrayList<STRING> getPhoneNumber() {
return
this
.phoneNumber;
}
}
</STRING></STRING></STRING>
|