I'm using java jaxb2.0
to do xml marshalling
and unmarshalling
.
I encountered a problem like this.
the sample xml is like this*(fruit.xml)*:
<fruitPacks>
<fruit name="apple1" type="apple" isApple="true"/>
<fruit name="banana1" type="banana" isBanana="true"/>
<fruit name="apple2" type="apple" isApple="true"/>
</fruitPacks>
and java class like this:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "fruitPacks")
@XmlRootElement
public class FruitPacks
{
@XmlElement(name = "fruit")
private List<Fruit> fruits
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "fruit")
@XmlSeeAlso({ Apple.class, Banana.class })
public class Fruit{
@XmlAttribute
private String name;
@XmlAttribute
private String type;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "apple")
public class Apple extends Fruit{
@XmlAttribute
private boolean isApple = true;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "banana")
public class Banana extends Fruit{
@XmlAttribute
private boolean isBanana = true;
}
and unmarshal code is :
public class JAXBTest {
public static void main(String [] args) throws Exception{
JAXBContext jc = JAXBContext.newInstance(FruitPacks.class,Fruit.class,Apple.class, Banana.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Object obj = unmarshaller.unmarshal(new File("fruit.xml"));
System.out.println(obj);
}
}
So what I want to do is:
when unmarshalling the xml, the construction of the fruit will automatically done to the subclasses (Apple, Banana) based on the type attribute.
How can i do it?
You need to ensure that your JAXBContext
is aware of the subclasses. One way to do this is to use the @XmlSeeAlso
annotation, see an example below:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "fruit")
@XmlSeeAlso({Apple.class, Banana.class})
public class Fruit{
@XmlAttribute
private String name;
@XmlAttribute
private String type;
}
For More Information
UPDATE
I just realized you are using the type
attribute and not the standard xsi:type
attribute. With any JAXB implementation you could map this use case leveraging an XmlAdapter
:
If you are using EclipseLink JAXB (MOXy) then you can leverage the @XmlDescriminatorNode
/@XmlDescriminatorValue
extension: