prev table of contents next

2.2.16.2 Another Content Tree as Element

It's also possible to insert an arbitrary content tree as an element. We'll assume that we have several document definitions, like this:

<xsd:complexType name="HearsayType">
  <xsd:sequence>
    <xsd:element name="text" type="xsd:string"/>
  </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="GrapevineType">
  <xsd:sequence>
    <xsd:element name="text" type="xsd:string"/>
  </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="RumourType">
  <xsd:sequence>
    <xsd:element name="text" type="xsd:string"/>
  </xsd:sequence>
</xsd:complexType>
We want any of these nice documents to be envelopped by a container document:
<xsd:complexType name="CommType">
  <xsd:sequence>
    <xsd:element name="source" type="xsd:string"/>
    <xsd:element name="comm"   type="xsd:anyType"/>
  </xsd:sequence>
</xsd:complexType>
There is no surprise in the classes generated by the JAXB compiler. (The comm sub-element of CommType has the type java.lang.Object.) So we can write some code to marshal such an XML communication.
ObjectFactory of = new ObjectFactory();

// Create the container object.
CommType comm = of.createCommType();
comm.setSource( "Ms Jones" );

// Let's have some hearsay.
HearsayType hearsay = of.createHearsayType();
hearsay.setText( "Mr. Harper does naughty things." );
comm.setComm( hearsay );

// Prepare a JAXBElement, ready for marshalling.
QName qn = new QName( "comm" );
JAXBElement<CommType> je =
    new JAXBElement<CommType>( qn, CommType.class, comm );
The JAXBElement is now ready to be passed to a Marshaller. The resulting XML text looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<comm>
  <source>Ms Jones</source>
  <comm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:type="HearsayType">
    <text>Mr. Harper does naughty things.</text>
  </comm>
</comm>
It should be satsifying to note that JAXB has annotated the comm element with xsi:type="HearsayType" which is going to help a lot during the inverse process. In fact, all you have to do to get this document unmarshalled into a content tree and to access the nested contents is this:
File f = new File( ... );
JAXBElement<CommType> je = (JAXBElement<CommType>)u.unmarshal( f );
CommType comm = (CommType)je.getValue();
if( comm.getComm() instanceof HearsayType ){
    HearsayType hearsay = (HearsayType)comm.getComm();
} else {
    // ...(investigate other possibilities)...
}


prev table of contents next