I am trying to unmarshall the following XML using JAXB:
<Works>
<Work>
<Composers>
<Composer>
<Name>A name</Name>
</Composer>
<Composer>
<Name>A name 2</Name>
</Composer>
</Composers>
</Work>
</Works>
I have generated all of the classes using XJC. If I want to access the Composers collection, I have to do this:
List<Composer> composers = work.getComposers().getComposer();
Is there any way I can do the following instead?
List<Composer> composers = work.getComposers();
I appreciate the need for a Composers object as it derived from the XML, but when dealing in Java, having an intermediate POJO that stores the collections seems a bit redundant.
My XSD is:
<xsd:complexType name="Works">
<xsd:sequence>
<xsd:element name="Work" type="Work" maxOccurs="unbounded" minOccurs="0"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Work">
<xsd:sequence>
<xsd:element name="Composers" type="Composers"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Composers">
<xsd:sequence>
<xsd:element name="Composer" type="Composer" maxOccurs="unbounded" minOccurs="0"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Composer">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
The @XmlElementWrapper plugin does exactly what you want.
For anybody who can not or does not want to use the plugin:
If you can live with a different XML structure, it's possible to avoid generating the extra wrapper classes by simply using maxoccurs="unbounded"
and leaving out the containing element. Using the original example:
<xsd:element name="Work" type="Work" maxOccurs="unbounded" minOccurs="0"/>
<xsd:complexType name="Work">
<xsd:sequence>
<xsd:element name="Composer" type="Composer" maxOccurs="unbounded" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Composer">
<xsd:sequence>
<xsd:element name="Name" type="xsd:string"></xsd:element>
</xsd:sequence>
</xsd:complexType>
will produce a structure like this:
<Work>
<Composer>
<Name>A name</Name>
</Composer>
<Composer>
<Name>A name 2</Name>
</Composer>
</Work>
This will put a method on the Work type that returns a List<Composer>
object. Unfortunately the method is called getComposer
instead of getComposers
, but you can use annotations or custom bindings to fix that problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With