| prev | table of contents | next |
XmlElementRef, XmlMixed
An XML complex type with mixed content, i.e., child elements embedded in
the element's own data, cannot be bound to a class in the usual
bean style, with one field for each element and attribute, and another
one for the content text. Doing so would lose the order of the
sub-elements and the chunks of content text wherein they are embedded.
JAXB binds such a type to a class containing a single list
attribute typed List<JAXBElement>. Here is a schema
snippet for a complex type with mixed content:
<xs:complexType name="MessageType" mixed="true">
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="code" type="CodeType"/>
</xs:sequence>
</xs:complexType>
To achieve the same effect with an annotated class, you would write
an annotated Java class like this:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MessageType", propOrder = {
"content"
})
public class MessageType {
@XmlElementRefs( {
@XmlElementRef(name = "code", type = JAXBElement.class),
@XmlElementRef(name = "id", type = JAXBElement.class) })
@XmlMixed
protected List<Serializable> content;
public List<Serializable> getContent() {
if (content == null) {
content = new ArrayList<Serializable>();
}
return this.content;
}
}
The generic parameter for the content list is Serializable,
slightly more specific than Object. When you process the
elements of the content list after unmarshalling, you'll have to
distinguish between JAXBElement objects for the sub-elements
and String objets for the chunks of the content of the
element itself.
A similar but rarely encountered situation is created by duplicating
an element in a sequence. Below is a slightly modified version of the
schema snippet for the complex type MessageType, which
doesn't have mixed content any more, but contains a repetition
of element id (ours not to worry why):
<xs:complexType name="MessageType">
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="code" type="CodeType"/>
<xs:element name="id" type="xs:int"/>
</xs:sequence>
</xs:complexType>
The annotated Java code would be similar to the one shown previously,
except that XmlMixed is omitted and the generic
parameter for List should be JAXBElement<?>.
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Message", propOrder = { "content" } )
public class Message {
@XmlElementRefs({
@XmlElementRef(name = "id", type = JAXBElement.class),
@XmlElementRef(name = "code", type = JAXBElement.class),
@XmlElementRef(name = "id", type = JAXBElement.class)
})
protected List<JAXBElement<?>> content;
public List<JAXBElement<?>> getContent() {
if (content == null) {
content = new ArrayList<JAXBElement<?>>();
}
return this.content;
}
}
This does, in fact, marshal or unmarshal many more sub-element
sequences than the one shown in the schema snippet, with arbitrary
alternations of all three elements.
| prev | table of contents | next |