Reputation: 49197
It would appear to be possible to unmarshal two different jaxb
objects with the same name.
There is a Bar
class ...
public abstract Bar {
private @XmlElement String val;
}
.. with Two implementations (constructors etc. left out):
@XmlRootElement(name="bar")
public class BarA extends Bar { }
@XmlRootElement(name="bar")
public class BarB extends Bar {
private @XmlElement(required=true) String type;
}
Lastly I want to unmarshall a list of Bar
documents from XML similar to the following
<bars>
<bar>
<val>1</val>
</bar>
<bar>
<val>1</val>
<type>2</type>
</bar>
</bars>
The list is wrapped in an class utilizing the @XmlAnyElement
@XmlRootElement
public class Bars {
@XmlMixed
@XmlAnyElement(lax = true)
@XmlElementRefs({@XmlElementRef(BarA.class), @XmlElementRef(BarB.class)})
private List<Bar> bars;
}
However I seem to only get instances of either BarA
or BarB
, whichever is the last element in the @XmlElementRefs
chain.
Testing code:
String xml = ...
JAXBContext jc = JAXBContext.newInstance(Bars.class);
ByteArrayInputStream in = new ByteArrayInputStream(xml.getBytes());
Bars bars = (Bars) jc.createUnmarshaller().unmarshal(in);
for (Bar bar : bars.getBars()) {
System.out.println(bar.getClass());
}
I don't think the XmlAdapter
suggested in JAXB @XmlElements, different types but same name? would neccesarily be the only approach either.
Upvotes: 6
Views: 6252
Reputation: 149047
You could use an XmlAdapter
to do this. Below are answers I gave to a similar question:
Upvotes: 3
Reputation: 8374
Really, the first thing I would try to do is eliminate the source of the problem - having two different JAXB classes with the same name. A situation like that is bound to cause headaches, for you and for the people who have to maintain your code.
If that's impossible... Maybe you could write another subclass called EveryBar, and always unmarshall to that. EveryBar would contain all the fields of every other Bar subclass. Then you'd have a post-processing step on your object tree that would examine the EveryBar, and swap it for an instance of whatever type is appropriate. Yeah, it's an ugly solution, but it's only slightly worse than the one from your link.
Upvotes: 3