Reputation: 715
I would like to achieve something like this.
<zoo>
<lion> ... </lion>
<dog> ... </dog>
</zoo>
I have this class here.
public class MainGroup {
private List<Widget> widgets;
@XmlAnyElement
public List<Widget> getWidgets() {
return widgets;
}
public void setWidgets(List<Widget> widgets) {
this.widgets = widgets;
}
}
And this Widget superclass has got subclasses such as Button, Combobox... I would like to achieve something like this.
<MainGroup>
<Button>...</Button>
<Combo>...</Combo>
</MainGroup>
I am having this exception
[com.sun.istack.internal.SAXException2: class com.test.Button nor any of its super
class is known to this context.
I tried adding @XmlElementRef but it is still not working.
@XmlElementRefs({
@XmlElementRef(name="Button", type=Button.class),
@XmlElementRef(name="Combo", type=Combo.class)
})
Upvotes: 3
Views: 4362
Reputation: 715
Ok, I am missing quite a lot of things out here.
It seems like I add to add this @XmlRootElement
annotation to my subclasses of Button and Combo to achieve that.
Can anyone explain to me why I need that annotation in my subclasses... I am confused, I thought an XML would only have a @XmlRootElement
which in my case should be in MainGroup
class.
Upvotes: 0
Reputation: 149007
Mapping your Use Case
My answer is based on information gathered from one of your related questions:
Since you are mapping classes for which you do not have the source (and therefore can't add JAXB annotations), I would recommend using the @XmlElements
mapping.
@XmlElements({
@XmlElement(name="Button", type=Button.class),
@XmlElement(name="Combo", type=Combo.class)
})
public List<Widget> getWidgets() {
return widgets;
}
@XmlElements
corresponds to the XML Schema concept of xsd:choice
.
About @XmlRootElement
Ok, I am missing quite a lot of things out here. It seems like I add to add this @XmlRootElement annotation to my subclasses of Button and Combo to achieve that.
Can anyone explain to me why I need that annotation in my subclasses... I am confused, I thought an XML would only have a @XmlRootElement which in my case should be in MainGroup class.
@XmlRootElement
corresponds to global elements in the XML schema, which involves more that just the root element in the document you are unmarshalling. I'll describe a couple of the roles below:
@XmlElementRef
@XmlElementRef
corresponds to the concept of substitution groups. In an XML Schema you can specify that one global element is substitutable for another. In JAXB @XmlRootElement
(and @XmlElementDecl
) is leveraged to specify global elements:
@XmlAnyElement
@XmlAnyElement
corresponds to the concept of xs:any in XML Schena. This is part of the document that is pretty free form. In JAXB when you map a property with @XmlAnyElement(lax=true)
it will convert elements matching @XmlRootElement
declarations into the corresponding domain objects.
Upvotes: 1