Reputation: 1674
How is this XML structure modeled in a JAXB class annotation?
<root>
<linksCollection>
<links>
<foo href="http://example.com/foo" rel="link"/>
</links>
<links>
<bar href="http://example.com/bar" rel="link"/>
</links>
</linksCollection>
</root>
Starting with the following root class, what is the Link class? How do you get each link with an unknown element name to be wrapped in the links element?
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElement
protected List<Link> linksCollection;
// etc.
}
The following attempt does not work:
@XmlRootElement(name = "links")
@XmlAccessorType(XmlAccessType.FIELD)
public class Link {
@XmlAnyElement
protected Object link;
@XmlAttribute
protected String href;
@XmlAttribute
protected String rel;
//etc.
}
Upvotes: 0
Views: 1299
Reputation: 8974
Your attempt with @XmlAnyElement
for the unknown elements is the right way, but you were missing the @XmlElementWrapper
for the collection. The following mapping produces a collection for those elements:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElementWrapper(name="linksCollection")
@XmlElement(name="links")
protected List<Link> linksCollection;
}
public class Link {
@XmlAnyElement(lax = true)
protected Object content;
}
According to this explanation you will have an instance of org.w3c.dom.Element in your collection if you do not specify a mapping.
If you have only a limited subset of unknown elements, you could change the annotation in the link class as follows:
@XmlElements({
@XmlElement(name = "foo", type = FooBar.class),
@XmlElement(name = "bar", type = FooBar.class) , ...})
protected Object content;
The FooBar class could then look like this:
public class FooBar {
@XmlAttribute(name = "href")
protected String href;
@XmlAttribute(name = "rel")
protected String rel;
}
However when you can't predict the possible tags, I would stay with the @XmlAnyElement
and add a @XmlTypeAdapter
. There is another thread: Jaxb complex xml unmarshall about this topic.
Upvotes: 2