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 |