In this example, you will want to use the annotations @XmlElementRef and @XmlRootElement . This is consistent with the concept of XML wildcard schemas. This will allow you to have a list of objects from the inheritance hierarchy differentiated by element.
Animals
This will serve as the root object for the domain model. It has a List property annotated with @XmlElementRef . This means that it will match the values ββbased on the value of their @XmlRootElement annotations.
package forum8356849; import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement(name="Animals") @XmlAccessorType(XmlAccessType.FIELD) @XmlSeeAlso({Cat.class, Dog.class}) public class Animals { @XmlElementRef private List<Animal> animals; }
Animal
package forum8356849; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) class Animal { String name; }
Cat
We annotate the Cat class using the @XmlRootElement annotation. This is used in tandem with the @XmlElementRef annotation on Animals .
package forum8356849; import javax.xml.bind.annotation.*; @XmlRootElement(name="Cat") class Cat extends Animal { int numLives; }
Dog
We will also add the @XmlRootElement annotation to the Dog class.
package forum8356849; import javax.xml.bind.annotation.*; @XmlRootElement(name="Dog") class Dog extends Animal { boolean hasSpots; }
Demo
You can use the following class to see that everything works as expected. input.xml matches the XML provided in your question.
package forum8356849; import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Animals.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum8356849/input.xml"); Animals animals = (Animals) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(animals, System.out); } }
For additional information
source share