Reputation: 2021
How can I use JAXB to serialize and deserialize the following XML, considering that tags complement1
, 2
and 3
are not required and XML might have complement4
, 5
, n
?
I thought about using @XmlAnyElement
annotation, but I need to know that the value "First" belongs to the first complement, "Second" to the second, etc.
<resource>
<id>Identifier</id>
<name>Name</name>
<complement1>First</complement1>
<complement2>Second</complement2>
<complement3>Third</complement3>
</resource>
Upvotes: 4
Views: 2848
Reputation: 3849
I believe you can use @XmlAnyElement, and you do have access to the element name.
You need to use a "List of any" construct.
When JAXB unmarshalls the XML you will have a list of DOM Element objects, each of which contains the element name and contents.
I think you'd have to manually enforce that each element tag name matched the "complementN" pattern.
e.g. this is modified from one of the Oracle samples:
Schema:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
Snippet from xjc generated Person class:
...
@XmlRootElement(name = "person")
public class Person {
@XmlElement(required = true)
protected String firstname;
@XmlElement(required = true)
protected String lastname;
@XmlAnyElement(lax = true)
protected List<Object> any;
...
Test XML file:
<?xml version="1.0" encoding="utf-8"?>
<person>
<firstname>David</firstname>
<lastname>Francis</lastname>
<anyItem1>anyItem1Value</anyItem1>
<anyItem2>anyItem2Value</anyItem2>
</person>
Test class:
JAXBContext jc = JAXBContext.newInstance( "generated" );
Unmarshaller u = jc.createUnmarshaller();
Person contents = (Person) u.unmarshal(Testit.class.getResource("./anysample_test1.xml"));
System.out.println("contents: " + contents);
System.out.println(" firstname: " + contents.getFirstname());
System.out.println(" lastname: " + contents.getLastname());
System.out.println(" any: ");
for (Object anyItem : contents.getAny()) {
System.out.println(" any item: " + anyItem);
Element ele = (Element) anyItem;
System.out.println(" ele name: " + ele.getTagName());
System.out.println(" ele text content: " + ele.getTextContent());
}
Output:
contents: generated.Person@1bfc93a
firstname: David
lastname: Francis
any:
any item: [anyItem1: null]
ele name: anyItem1
ele text content: anyItem1Value
any item: [anyItem2: null]
ele name: anyItem2
ele text content: anyItem2Value
Upvotes: 6