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.
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.
You could use an XmlAdapter
to do this. Below are answers I gave to a similar question:
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