Chapter 35. Using Complex Types
Abstract
Complex types can contain multiple elements and they can have attributes. They are mapped into Java classes that can hold the data represented by the type definition. Typically, the mapping is to a bean with a set of properties representing the elements and the attributes of the content model..
35.1. Basic Complex Type Mapping
Overview
XML Schema complex types define constructs containing more complex information than a simple type. The most simple complex types define an empty element with an attribute. More intricate complex types are made up of a collection of elements.
By default, an XML Schema complex type is mapped to a Java class, with a member variable to represent each element and attribute listed in the XML Schema definition. The class has setters and getters for each member variable.
Defining in XML Schema
XML Schema complex types are defined using the complexType
element. The complexType
element wraps the rest of elements used to define the structure of the data. It can appear either as the parent element of a named type definition, or as the child of an element
element anonymously defining the structure of the information stored in the element. When the complexType
element is used to define a named type, it requires the use of the name
attribute. The name
attribute specifies a unique identifier for referencing the type.
Complex type definitions that contain one or more elements have one of the child elements described in Table 35.1, “Elements for Defining How Elements Appear in a Complex Type”. These elements determine how the specified elements appear in an instance of the type.
Element | Description |
---|---|
| All of the elements defined as part of the complex type must appear in an instance of the type. However, they can appear in any order. |
| Only one of the elements defined as part of the complex type can appear in an instance of the type. |
| All of the elements defined as part of the complex type must appear in an instance of the type, and they must also appear in the order specified in the type definition. |
If a complex type definition only uses attributes, you do not need one of the elements described in Table 35.1, “Elements for Defining How Elements Appear in a Complex Type”.
After deciding how the elements will appear, you define the elements by adding one or more element
element children to the definition.
Example 35.1, “XML Schema Complex Type” shows a complex type definition in XML Schema.
Example 35.1. XML Schema Complex Type
<complexType name="sequence"> <sequence> <element name="name" type="xsd:string" /> <element name="street" type="xsd:short" /> <element name="city" type="xsd:string" /> <element name="state" type="xsd:string" /> <element name="zipCode" type="xsd:string" /> </sequence> </complexType>
Mapping to Java
XML Schema complex types are mapped to Java classes. Each element in the complex type definition is mapped to a member variable in the Java class. Getter and setter methods are also generated for each element in the complex type.
All generated Java classes are decorated with the @XmlType
annotation. If the mapping is for a named complex type, the annotations name
is set to the value of the complexType
element’s name
attribute. If the complex type is defined as part of an element definition, the value of the @XmlType
annotation’s name
property is the value of the element
element’s name
attribute.
As described in the section called “Java mapping of elements with an in-line type”, the generated class is decorated with the @XmlRootElement
annotation if it is generated for a complex type defined as part of an element definition.
To provide the runtime with guidelines indicating how the elements of the XML Schema complex type should be handled, the code generators alter the annotations used to decorate the class and its member variables.
- All Complex Type
All complex types are defined using the
all
element. They are annotated as follows:-
The
@XmlType
annotation’spropOrder
property is empty. -
Each element is decorated with the
@XmlElement
annotation. The
@XmlElement
annotation’srequired
property is set totrue
.Example 35.2, “Mapping of an All Complex Type” shows the mapping for an all complex type with two elements.
Example 35.2. Mapping of an All Complex Type
@XmlType(name = "all", propOrder = { }) public class All { @XmlElement(required = true) protected BigDecimal amount; @XmlElement(required = true) protected String type; public BigDecimal getAmount() { return amount; } public void setAmount(BigDecimal value) { this.amount = value; } public String getType() { return type; } public void setType(String value) { this.type = value; } }
-
The
- Choice Complex Type
Choice complex types are defined using the
choice
element. They are annotated as follows:-
The
@XmlType
annotation’spropOrder
property lists the names of the elements in the order they appear in the XML Schema definition. None of the member variables are annotated.
Example 35.3, “Mapping of a Choice Complex Type” shows the mapping for a choice complex type with two elements.
Example 35.3. Mapping of a Choice Complex Type
@XmlType(name = "choice", propOrder = { "address", "floater" }) public class Choice { protected Sequence address; protected Float floater; public Sequence getAddress() { return address; } public void setAddress(Sequence value) { this.address = value; } public Float getFloater() { return floater; } public void setFloater(Float value) { this.floater = value; } }
-
The
- Sequence Complex Type
A sequence complex type is defined using the
sequence
element. It is annotated as follows:-
The
@XmlType
annotation’spropOrder
property lists the names of the elements in the order they appear in the XML Schema definition. -
Each element is decorated with the
@XmlElement
annotation. The
@XmlElement
annotation’srequired
property is set totrue
.Example 35.4, “Mapping of a Sequence Complex Type” shows the mapping for the complex type defined in Example 35.1, “XML Schema Complex Type”.
Example 35.4. Mapping of a Sequence Complex Type
@XmlType(name = "sequence", propOrder = { "name", "street", "city", "state", "zipCode" }) public class Sequence { @XmlElement(required = true) protected String name; protected short street; @XmlElement(required = true) protected String city; @XmlElement(required = true) protected String state; @XmlElement(required = true) protected String zipCode; public String getName() { return name; } public void setName(String value) { this.name = value; } public short getStreet() { return street; } public void setStreet(short value) { this.street = value; } public String getCity() { return city; } public void setCity(String value) { this.city = value; } public String getState() { return state; } public void setState(String value) { this.state = value; } public String getZipCode() { return zipCode; } public void setZipCode(String value) { this.zipCode = value; } }
-
The
35.2. Attributes
Overview
Apache CXF supports the use of attribute
elements and attributeGroup
elements within the scope of a complexType
element. When defining structures for an XML document attribute declarations provide a means of adding information that is specified within the tag, not the value that the tag contains. For example, when describing the XML element <value currency="euro">410<\value> in XML Schema the currency
attribute is described using an attribute
element as shown in Example 35.5, “XML Schema Defining and Attribute”.
The attributeGroup
element allows you to define a group of reusable attributes that can be referenced by all complex types defined by the schema. For example, if you are defining a series of elements that all use the attributes category
and pubDate
, you could define an attribute group with these attributes and reference them in all the elements that use them. This is shown in Example 35.7, “Attribute Group Definition”.
When describing data types for use in developing application logic, attributes whose use
attribute is set to either optional
or required
are treated as elements of a structure. For each attribute declaration contained within a complex type description, an element is generated in the class for the attribute, along with the appropriate getter and setter methods.
Defining an attribute in XML Schema
An XML Schema attribute
element has one required attribute, name
, that is used to identify the attribute. It also has four optional attributes that are described in Table 35.2, “Optional Attributes Used to Define Attributes in XML Schema”.
Attribute | Description |
---|---|
|
Specifies if the attribute is required. Valid values are |
| Specifies the type of value the attribute can take. If it is not used the schema type of the attribute must be defined in-line. |
|
Specifies a default value to use for the attribute. It is only used when the |
|
Specifies a fixed value to use for the attribute. It is only used when the |
Example 35.5, “XML Schema Defining and Attribute” shows an attribute element defining an attribute, currency, whose value is a string.
Example 35.5. XML Schema Defining and Attribute
<element name="value"> <complexType> <xsd:simpleContent> <xsd:extension base="xsd:integer"> <xsd:attribute name="currency" type="xsd:string" use="required"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element>
If the type
attribute is omitted from the attribute
element, the format of the data must be described in-line. Example 35.6, “Attribute with an In-Line Data Description” shows an attribute
element for an attribute, category
, that can take the values autobiography
, non-fiction
, or fiction
.
Example 35.6. Attribute with an In-Line Data Description
<attribute name="category" use="required"> <simpleType> <restriction base="xsd:string"> <enumeration value="autobiography"/> <enumeration value="non-fiction"/> <enumeration value="fiction"/> </restriction> </simpleType> </attribute>
Using an attribute group in XML Schema
Using an attribute group in a complex type definition is a two step process:
Define the attribute group.
An attribute group is defined using an
attributeGroup
element with a number ofattribute
child elements. TheattributeGroup
requires aname
attribute that defines the string used to refer to the attribute group. Theattribute
elements define the members of the attribute group and are specified as shown in the section called “Defining an attribute in XML Schema”. Example 35.7, “Attribute Group Definition” shows the description of the attribute groupcatalogIndecies
. The attribute group has two members:category
, which is optional, andpubDate
, which is required.Example 35.7. Attribute Group Definition
<attributeGroup name="catalogIndices"> <attribute name="category" type="catagoryType" /> <attribute name="pubDate" type="dateTime" use="required" /> </attributeGroup>
Use the attribute group in the definition of a complex type.
You use attribute groups in complex type definitions by using the
attributeGroup
element with theref
attribute. The value of theref
attribute is the name given the attribute group that you want to use as part of the type definition. For example if you want to use the attribute groupcatalogIndecies
in the complex typedvdType
, you would use <attributeGroup ref="catalogIndecies" /> as shown in Example 35.8, “Complex Type with an Attribute Group”.Example 35.8. Complex Type with an Attribute Group
<complexType name="dvdType"> <sequence> <element name="title" type="xsd:string" /> <element name="director" type="xsd:string" /> <element name="numCopies" type="xsd:int" /> </sequence> <attributeGroup ref="catalogIndices" /> </complexType>
Mapping attributes to Java
Attributes are mapped to Java in much the same way that member elements are mapped to Java. Required attributes and optional attributes are mapped to member variables in the generated Java class. The member variables are decorated with the @XmlAttribute
annotation. If the attribute is required, the @XmlAttribute
annotation’s required
property is set to true
.
The complex type defined in Example 35.9, “techDoc Description” is mapped to the Java class shown in Example 35.10, “techDoc Java Class”.
Example 35.9. techDoc Description
<complexType name="techDoc"> <all> <element name="product" type="xsd:string" /> <element name="version" type="xsd:short" /> </all> <attribute name="usefullness" type="xsd:float" use="optional" default="0.01" /> </complexType>
Example 35.10. techDoc Java Class
@XmlType(name = "techDoc", propOrder = { }) public class TechDoc { @XmlElement(required = true) protected String product; protected short version; @XmlAttribute protected Float usefullness; public String getProduct() { return product; } public void setProduct(String value) { this.product = value; } public short getVersion() { return version; } public void setVersion(short value) { this.version = value; } public float getUsefullness() { if (usefullness == null) { return 0.01F; } else { return usefullness; } } public void setUsefullness(Float value) { this.usefullness = value; } }
As shown in Example 35.10, “techDoc Java Class”, the default
attribute and the fixed
attribute instruct the code generators to add code to the getter method generated for the attribute. This additional code ensures that the specified value is returned if no value is set.
The fixed
attribute is treated the same as the default
attribute. If you want the fixed
attribute to be treated as a Java constant you can use the customization described in Section 38.5, “Customizing Fixed Value Attribute Mapping”.
Mapping attribute groups to Java
Attribute groups are mapped to Java as if the members of the group were explicitly used in the type definition. If the attribute group has three members, and it is used in a complex type, the generated class for that type will include a member variable, along with the getter and setter methods, for each member of the attribute group. For example, the complex type defined in Example 35.8, “Complex Type with an Attribute Group”, Apache CXF generates a class containing the member variables category
and pubDate
to support the members of the attribute group as shown in Example 35.11, “dvdType Java Class”.
Example 35.11. dvdType Java Class
@XmlType(name = "dvdType", propOrder = {
"title",
"director",
"numCopies"
})
public class DvdType {
@XmlElement(required = true)
protected String title;
@XmlElement(required = true)
protected String director;
protected int numCopies;
@XmlAttribute protected CatagoryType category; @XmlAttribute(required = true) @XmlSchemaType(name = "dateTime") protected XMLGregorianCalendar pubDate;
public String getTitle() {
return title;
}
public void setTitle(String value) {
this.title = value;
}
public String getDirector() {
return director;
}
public void setDirector(String value) {
this.director = value;
}
public int getNumCopies() {
return numCopies;
}
public void setNumCopies(int value) {
this.numCopies = value;
}
public CatagoryType getCatagory() {
return catagory;
}
public void setCatagory(CatagoryType value) {
this.catagory = value;
}
public XMLGregorianCalendar getPubDate() {
return pubDate;
}
public void setPubDate(XMLGregorianCalendar value) {
this.pubDate = value;
}
}
35.3. Deriving Complex Types from Simple Types
Overview
Apache CXF supports derivation of a complex type from a simple type. A simple type has, by definition, neither sub-elements nor attributes. Hence, one of the main reasons for deriving a complex type from a simple type is to add attributes to the simple type.
There are two ways of deriving a complex type from a simple type:
Derivation by extension
Example 35.12, “Deriving a Complex Type from a Simple Type by Extension” shows an example of a complex type, internationalPrice
, derived by extension from the xsd:decimal
primitive type to include a currency attribute.
Example 35.12. Deriving a Complex Type from a Simple Type by Extension
<complexType name="internationalPrice"> <simpleContent> <extension base="xsd:decimal"> <attribute name="currency" type="xsd:string"/> </extension> </simpleContent> </complexType>
The simpleContent
element indicates that the new type does not contain any sub-elements. The extension
element specifies that the new type extends xsd:decimal
.
Derivation by restriction
Example 35.13, “Deriving a Complex Type from a Simple Type by Restriction” shows an example of a complex type, idType
, that is derived by restriction from xsd:string
. The defined type restricts the possible values of xsd:string
to values that are ten characters in length. It also adds an attribute to the type.
Example 35.13. Deriving a Complex Type from a Simple Type by Restriction
<complexType name="idType"> <simpleContent> <restriction base="xsd:string"> <length value="10" /> <attribute name="expires" type="xsd:dateTime" /> </restriction> </simpleContent> </complexType>
As in Example 35.12, “Deriving a Complex Type from a Simple Type by Extension” the simpleContent
element signals that the new type does not contain any children. This example uses a restriction
element to constrain the possible values used in the new type. The attribute
element adds the element to the new type.
Mapping to Java
A complex type derived from a simple type is mapped to a Java class that is decorated with the @XmlType
annotation. The generated class contains a member variable, value
, of the simple type from which the complex type is derived. The member variable is decorated with the @XmlValue
annotation. The class also has a getValue()
method and a setValue()
method. In addition, the generated class has a member variable, and the associated getter and setter methods, for each attribute that extends the simple type.
Example 35.14, “idType Java Class” shows the Java class generated for the idType
type defined in Example 35.13, “Deriving a Complex Type from a Simple Type by Restriction”.
Example 35.14. idType Java Class
@XmlType(name = "idType", propOrder = { "value" }) public class IdType { @XmlValue protected String value; @XmlAttribute @XmlSchemaType(name = "dateTime") protected XMLGregorianCalendar expires; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public XMLGregorianCalendar getExpires() { return expires; } public void setExpires(XMLGregorianCalendar value) { this.expires = value; } }
35.4. Deriving Complex Types from Complex Types
Overview
Using XML Schema, you can derive new complex types by either extending or restricting other complex types using the complexContent
element. When generating the Java class to represent the derived complex type, Apache CXF extends the base type’s class. In this way, the generated Java code preserves the inheritance hierarchy intended in the XML Schema.
Schema syntax
You derive complex types from other complex types by using the complexContent
element, and either the extension
element or the restriction
element. The complexContent
element specifies that the included data description includes more than one field. The extension
element and the restriction
element, which are children of the complexContent
element, specify the base type being modified to create the new type. The base type is specified by the base
attribute.
Extending a complex type
To extend a complex type use the extension
element to define the additional elements and attributes that make up the new type. All elements that are allowed in a complex type description are allowable as part of the new type’s definition. For example, you can add an anonymous enumeration to the new type, or you can use the choice
element to specify that only one of the new fields can be valid at a time.
Example 35.15, “Deriving a Complex Type by Extension” shows an XML Schema fragment that defines two complex types, widgetOrderInfo
and widgetOrderBillInfo
. widgetOrderBillInfo
is derived by extending widgetOrderInfo
to include two new elements: orderNumber
and amtDue
.
Example 35.15. Deriving a Complex Type by Extension
<complexType name="widgetOrderInfo"> <sequence> <element name="amount" type="xsd:int"/> <element name="order_date" type="xsd:dateTime"/> <element name="type" type="xsd1:widgetSize"/> <element name="shippingAddress" type="xsd1:Address"/> </sequence> <attribute name="rush" type="xsd:boolean" use="optional" /> </complexType> <complexType name="widgetOrderBillInfo"> <complexContent> <extension base="xsd1:widgetOrderInfo"> <sequence> <element name="amtDue" type="xsd:decimal"/> <element name="orderNumber" type="xsd:string"/> </sequence> <attribute name="paid" type="xsd:boolean" default="false" /> </extension> </complexContent> </complexType>
Restricting a complex type
To restrict a complex type use the restriction
element to limit the possible values of the base type’s elements or attributes. When restricting a complex type you must list all of the elements and attributes of the base type. For each element you can add restrictive attributes to the definition. For example, you can add a maxOccurs
attribute to an element to limit the number of times it can occur. You can also use the fixed
attribute to force one or more of the elements to have predetermined values.
Example 35.16, “Defining a Complex Type by Restriction” shows an example of defining a complex type by restricting another complex type. The restricted type, wallawallaAddress
, can only be used for addresses in Walla Walla, Washington because the values for the city
element, the state
element, and the zipCode
element are fixed.
Example 35.16. Defining a Complex Type by Restriction
<complexType name="Address"> <sequence> <element name="name" type="xsd:string"/> <element name="street" type="xsd:short" maxOccurs="3"/> <element name="city" type="xsd:string"/> <element name="state" type="xsd:string"/> <element name="zipCode" type="xsd:string"/> </sequence> </complexType> <complexType name="wallawallaAddress"> <complexContent> <restriction base="xsd1:Address"> <sequence> <element name="name" type="xsd:string"/> <element name="street" type="xsd:short" maxOccurs="3"/> <element name="city" type="xsd:string" fixed="WallaWalla"/> <element name="state" type="xsd:string" fixed="WA" /> <element name="zipCode" type="xsd:string" fixed="99362" /> </sequence> </restriction> </complexContent> </complexType>
Mapping to Java
As it does with all complex types, Apache CXF generates a class to represent complex types derived from another complex type. The Java class generated for the derived complex type extends the Java class generated to support the base complex type. The base Java class is also modified to include the @XmlSeeAlso
annotation. The base class' @XmlSeeAlso
annotation lists all of the classes that extend the base class.
When the new complex type is derived by extension, the generated class will include member variables for all of the added elements and attributes. The new member variables will be generated according to the same mappings as all other elements.
When the new complex type is derived by restriction, the generated class will have no new member variables. The generated class will simply be a shell that does not provide any additional functionality. It is entirely up to you to ensure that the restrictions defined in the XML Schema are enforced.
For example, the schema in Example 35.15, “Deriving a Complex Type by Extension” results in the generation of two Java classes: WidgetOrderInfo
and WidgetBillOrderInfo
. WidgetOrderBillInfo
extends WidgetOrderInfo
because widgetOrderBillInfo
is derived by extension from widgetOrderInfo
. Example 35.17, “WidgetOrderBillInfo” shows the generated class for widgetOrderBillInfo
.
Example 35.17. WidgetOrderBillInfo
@XmlType(name = "widgetOrderBillInfo", propOrder = { "amtDue", "orderNumber" }) public class WidgetOrderBillInfo extends WidgetOrderInfo { @XmlElement(required = true) protected BigDecimal amtDue; @XmlElement(required = true) protected String orderNumber; @XmlAttribute protected Boolean paid; public BigDecimal getAmtDue() { return amtDue; } public void setAmtDue(BigDecimal value) { this.amtDue = value; } public String getOrderNumber() { return orderNumber; } public void setOrderNumber(String value) { this.orderNumber = value; } public boolean isPaid() { if (paid == null) { return false; } else { return paid; } } public void setPaid(Boolean value) { this.paid = value; } }
35.5. Occurrence Constraints
35.5.1. Schema Elements Supporting Occurrence Constraints
XML Schema allows you to specify the occurrence constraints on four of the XML Schema elements that make up a complex type definition:
35.5.2. Occurrence Constraints on the All Element
XML Schema
Complex types defined with the all
element do not allow for multiple occurrences of the structure defined by the all
element. You can, however, make the structure defined by the all
element optional by setting its minOccurs
attribute to 0
.
Mapping to Java
Setting the all
element’s minOccurs
attribute to 0
has no effect on the generated Java class.
35.5.3. Occurrence Constraints on the Choice Element
Overview
By default, the results of a choice
element can only appear once in an instance of a complex type. You can change the number of times the element chosen to represent the structure defined by a choice
element is allowed to appear using its minOccurs
attribute and its mxOccurs
attribute. Using these attributes you can specify that the choice type can occur zero to an unlimited number of times in an instance of a complex type. The element chosen for the choice type does not need to be the same for each occurrence of the type.
Using in XML Schema
The minOccurs
attribute specifies the minimum number of times the choice type must appear. Its value can be any positive integer. Setting the minOccurs
attribute to 0
specifies that the choice type does not need to appear inside an instance of the complex type.
The maxOccurs
attribute specifies the maximum number of times the choice type can appear. Its value can be any non-zero, positive integer or unbounded
. Setting the maxOccurs
attribute to unbounded
specifies that the choice type can appear an infinite number of times.
Example 35.18, “Choice Occurrence Constraints” shows the definition of a choice type, ClubEvent
, with choice occurrence constraints. The choice type overall can be repeated 0 to unbounded times.
Example 35.18. Choice Occurrence Constraints
<complexType name="ClubEvent"> <choice minOccurs="0" maxOccurs="unbounded"> <element name="MemberName" type="xsd:string"/> <element name="GuestName" type="xsd:string"/> </choice> </complexType>
Mapping to Java
Unlike single instance choice structures, XML Schema choice structures that can occur multiple times are mapped to a Java class with a single member variable. This single member variable is a List<T>
object that holds all of the data for the multiple occurrences of the sequence. For example, if the sequence defined in Example 35.18, “Choice Occurrence Constraints” occurred two times, then the list would have two items.
The name of the Java class' member variable is derived by concatenating the names of the member elements. The element names are separated by Or
and the first letter of the variable name is converted to lower case. For example, the member variable generated from Example 35.18, “Choice Occurrence Constraints” would be named memberNameOrGuestName
.
The type of object stored in the list depends on the relationship between the types of the member elements. For example:
-
If the member elements are of the same type the generated list will contain
JAXBElement<T>
objects. The base type of theJAXBElement<T>
objects is determined by the normal mapping of the member elements' type. - If the member elements are of different types and their Java representations implement a common interface, the list will contains objects of the common interface.
- If the member elements are of different types and their Java representations extend a common base class, the list will contains objects of the common base class.
-
If none of the other conditions are met, the list will contain
Object
objects.
The generated Java class will only have a getter method for the member variable. The getter method returns a reference to the live list. Any modifications made to the returned list will effect the actual object.
The Java class is decorated with the @XmlType
annotation. The annotation’s name
property is set to the value of the name
attribute from the parent element of the XML Schema definition. The annotation’s propOrder
property contains the single member variable representing the elements in the sequence.
The member variable representing the elements in the choice structure are decorated with the @XmlElements
annotation. The @XmlElements
annotation contains a comma separated list of @XmlElement
annotations. The list has one @XmlElement
annotation for each member element defined in the XML Schema definition of the type. The @XmlElement
annotations in the list have their name
property set to the value of the XML Schema element
element’s name
attribute and their type
property set to the Java class resulting from the mapping of the XML Schema element
element’s type.
Example 35.19, “Java Representation of Choice Structure with an Occurrence Constraint” shows the Java mapping for the XML Schema choice structure defined in Example 35.18, “Choice Occurrence Constraints”.
Example 35.19. Java Representation of Choice Structure with an Occurrence Constraint
@XmlType(name = "ClubEvent", propOrder = { "memberNameOrGuestName" }) public class ClubEvent { @XmlElementRefs({ @XmlElementRef(name = "GuestName", type = JAXBElement.class), @XmlElementRef(name = "MemberName", type = JAXBElement.class) }) protected List<JAXBElement<String>> memberNameOrGuestName; public List<JAXBElement<String>> getMemberNameOrGuestName() { if (memberNameOrGuestName == null) { memberNameOrGuestName = new ArrayList<JAXBElement<String>>(); } return this.memberNameOrGuestName; } }
minOccurs set to 0
If only the minOccurs
element is specified and its value is 0
, the code generators generate the Java class as if the minOccurs
attribute were not set.
35.5.4. Occurrence Constraints on Elements
Overview
You can specify how many times a specific element in a complex type appears using the element
element’s minOccurs
attribute and maxOccurs
attribute. The default value for both attributes is 1
.
minOccurs set to 0
When you set one of the complex type’s member element’s minOccurs
attribute to 0
, the @XmlElement
annotation decorating the corresponding Java member variable is changed. Instead of having its required
property set to true
, the @XmlElement
annotation’s required
property is set to false
.
minOccurs set to a value greater than 1
In XML Schema you can specify that an element must occur more than once in an instance of the type by setting the element
element’s minOccurs
attribute to a value greater than one. However, the generated Java class will not support the XML Schema constraint. Apache CXF generates the supporting Java member variable as if the minOccurs
attribute were not set.
Elements with maxOccurs set
When you want a member element to appear multiple times in an instance of a complex type, you set the element’s maxOccurs
attribute to a value greater than 1. You can set the maxOccurs
attribute’s value to unbounded
to specify that the member element can appear an unlimited number of times.
The code generators map a member element with the maxOccurs
attribute set to a value greater than 1 to a Java member variable that is a List<T>
object. The base class of the list is determined by mapping the element’s type to Java. For XML Schema primitive types, the wrapper classes are used as described in the section called “Wrapper classes”. For example, if the member element is of type xsd:int
the generated member variable is a List<Integer>
object.
35.5.5. Occurrence Constraints on Sequences
Overview
By default, the contents of a sequence
element can only appear once in an instance of a complex type. You can change the number of times the sequence of elements defined by a sequence
element is allowed to appear using its minOccurs
attribute and its maxOccurs
attribute. Using these attributes you can specify that the sequence type can occur zero to an unlimited number of times in an instance of a complex type.
Using XML Schema
The minOccurs
attribute specifies the minimum number of times the sequence must occur in an instance of the defined complex type. Its value can be any positive integer. Setting the minOccurs
attribute to 0
specifies that the sequence does not need to appear inside an instance of the complex type.
The maxOccurs
attribute specifies the upper limit for how many times the sequence can occur in an instance of the defined complex type. Its value can be any non-zero, positive integer or unbounded
. Setting the maxOccurs
attribute to unbounded
specifies that the sequence can appear an infinite number of times.
Example 35.20, “Sequence with Occurrence Constraints” shows the definition of a sequence type, CultureInfo
, with sequence occurrence constraints. The sequence can be repeated 0 to 2 times.
Example 35.20. Sequence with Occurrence Constraints
<complexType name="CultureInfo"> <sequence minOccurs="0" maxOccurs="2"> <element name="Name" type="string"/> <element name="Lcid" type="int"/> </sequence> </complexType>
Mapping to Java
Unlike single instance sequences, XML Schema sequences that can occur multiple times are mapped to a Java class with a single member variable. This single member variable is a List<T>
object that holds all of the data for the multiple occurrences of the sequence. For example, if the sequence defined in Example 35.20, “Sequence with Occurrence Constraints” occurred two times, then the list would have four items.
The name of the Java class' member variable is derived by concatenating the names of the member elements. The element names are separated by And
and the first letter of the variable name is converted to lower case. For example, the member variable generated from Example 35.20, “Sequence with Occurrence Constraints” is named nameAndLcid
.
The type of object stored in the list depends on the relationship between the types of the member elements. For example:
-
If the member elements are of the same type the generated list will contain
JAXBElement<T>
objects. The base type of theJAXBElement<T>
objects is determined by the normal mapping of the member elements' type. - If the member elements are of different types and their Java representations implement a common interface, the list will contains objects of the common interface.
- If the member elements are of different types and their Java representations extend a common base class, the list will contain objects of the common base class.
-
If none of the other conditions are met, the list will contain
Object
objects.
The generated Java class only has a getter method for the member variable. The getter method returns a reference to the live list. Any modifications made to the returned list effects the actual object.
The Java class is decorated with the @XmlType
annotation. The annotation’s name
property is set to the value of the name
attribute from the parent element of the XML Schema definition. The annotation’s propOrder
property contains the single member variable representing the elements in the sequence.
The member variable representing the elements in the sequence are decorated with the @XmlElements
annotation. The @XmlElements
annotation contains a comma separated list of @XmlElement
annotations. The list has one @XmlElement
annotation for each member element defined in the XML Schema definition of the type. The @XmlElement
annotations in the list have their name
property set to the value of the XML Schema element
element’s name
attribute and their type
property set to the Java class resulting from the mapping of the XML Schema element
element’s type.
Example 35.21, “Java Representation of Sequence with an Occurrence Constraint” shows the Java mapping for the XML Schema sequence defined in Example 35.20, “Sequence with Occurrence Constraints”.
Example 35.21. Java Representation of Sequence with an Occurrence Constraint
@XmlType(name = "CultureInfo", propOrder = { "nameAndLcid" }) public class CultureInfo { @XmlElements({ @XmlElement(name = "Name", type = String.class), @XmlElement(name = "Lcid", type = Integer.class) }) protected List<Serializable> nameAndLcid; public List<Serializable> getNameAndLcid() { if (nameAndLcid == null) { nameAndLcid = new ArrayList<Serializable>(); } return this.nameAndLcid; } }
minOccurs set to 0
If only the minOccurs
element is specified and its value is 0
, the code generators generate the Java class as if the minOccurs
attribute is not set.
35.6. Using Model Groups
Overview
XML Schema model groups are convenient shortcuts that allows you to reference a group of elements from a user-defined complex type.For example, you can define a group of elements that are common to several types in your application and then reference the group repeatedly. Model groups are defined using the group
element, and are similar to complex type definitions. The mapping of model groups to Java is also similar to the mapping for complex types.
Defining a model group in XML Schema
You define a model group in XML Schema using the group
element with the name
attribute. The value of the name
attribute is a string that is used to refer to the group throughout the schema. The group
element, like the complexType
element, can have the sequence
element, the all
element, or the choice
element as its immediate child.
Inside the child element, you define the members of the group using element
elements. For each member of the group, specify one element
element. Group members can use any of the standard attributes for the element
element including minOccurs
and maxOccurs
. So, if your group has three elements and one of them can occur up to three times, you define a group with three element
elements, one of which uses maxOccurs="3". Example 35.22, “XML Schema Model Group” shows a model group with three elements.
Example 35.22. XML Schema Model Group
<group name="passenger"> <sequence> <element name="name" type="xsd:string" /> <element name="clubNum" type="xsd:long" /> <element name="seatPref" type="xsd:string" maxOccurs="3" /> </sequence> </group>
Using a model group in a type definition
Once a model group has been defined, it can be used as part of a complex type definition. To use a model group in a complex type definition, use the group
element with the ref
attribute. The value of the ref
attribute is the name given to the group when it was defined. For example, to use the group defined in Example 35.22, “XML Schema Model Group” you use <group ref="tns:passenger" /> as shown in Example 35.23, “Complex Type with a Model Group”.
Example 35.23. Complex Type with a Model Group
<complexType name="reservation">
<sequence>
<group ref="tns:passenger" />
<element name="origin" type="xsd:string" />
<element name="destination" type="xsd:string" />
<element name="fltNum" type="xsd:long" />
</sequence>
</complexType>
When a model group is used in a type definition, the group becomes a member of the type. So an instance of reservation
has four member elements. The first element is the passenger
element and it contains the member elements defined by the group shown in Example 35.22, “XML Schema Model Group”. An example of an instance of reservation
is shown in Example 35.24, “Instance of a Type with a Model Group”.
Example 35.24. Instance of a Type with a Model Group
<reservation>
<passenger> <name>A. Smart</name> <clubNum>99</clubNum> <seatPref>isle1</seatPref> </passenger>
<origin>LAX</origin>
<destination>FRA</destination>
<fltNum>34567</fltNum>
</reservation>
Mapping to Java
By default, a model group is only mapped to Java artifacts when it is included in a complex type definition. When generating code for a complex type that includes a model group, Apache CXF simply includes the member variables for the model group into the Java class generated for the type. The member variables representing the model group are annotated based on the definitions of the model group.
Example 35.25, “Type with a Group” shows the Java class generated for the complex type defined in Example 35.23, “Complex Type with a Model Group”.
Example 35.25. Type with a Group
@XmlType(name = "reservation", propOrder = { "name", "clubNum", "seatPref", "origin", "destination", "fltNum" }) public class Reservation { @XmlElement(required = true) protected String name; protected long clubNum; @XmlElement(required = true) protected List<String> seatPref; @XmlElement(required = true) protected String origin; @XmlElement(required = true) protected String destination; protected long fltNum; public String getName() { return name; } public void setName(String value) { this.name = value; } public long getClubNum() { return clubNum; } public void setClubNum(long value) { this.clubNum = value; } public List<String> getSeatPref() { if (seatPref == null) { seatPref = new ArrayList<String>(); } return this.seatPref; } public String getOrigin() { return origin; } public void setOrigin(String value) { this.origin = value; } public String getDestination() { return destination; } public void setDestination(String value) { this.destination = value; } public long getFltNum() { return fltNum; } public void setFltNum(long value) { this.fltNum = value; }
Multiple occurrences
You can specify that the model group appears more than once by setting the group
element’s maxOccurs
attribute to a value greater than one. To allow for multiple occurrences of the model group Apache CXF maps the model group to a List<T>
object. The List<T>
object is generated following the rules for the group’s first child:
-
If the group is defined using a
sequence
element see Section 35.5.5, “Occurrence Constraints on Sequences”. -
If the group is defined using a
choice
element see Section 35.5.3, “Occurrence Constraints on the Choice Element”.