JAXB and collection inheritance

how can I map (via JAXB in java 1.6) a compilation in XML and XML, where

class mapping{ @XmlElementWrapper(name="list") @XmlElement(name="item") Collection<A> list; } abstract class A{ } class B extends A{ public String onlyB; } class C extends A{ public String onlyC; } 

a would like to see XML as follows:

 <something> (doesnt matter, I'm using it in another structure) <list> <item xsi:type="b"><onlyB>b</onlyB></item> <item xsi:type="c"><onlyC>c</onlyC></item> </list> </something> 

works if I

 class mapping{ @XmlElement(name="item") A item; } 

I already tried xmlelementref, but without success

and I don't want to use @XmlElements({@XmlElement ...}) , because another project that uses this can add a derived class from A

+7
source share
1 answer

Your display looks correct. You must ensure that classes B and C are included when creating the JAXBContext. One way to achieve this is to use @XmlSeeAlso .

 @XmlSeeAlso(B.class, C.class) abstract class A{ } 

The following is an example of using xsi:type to represent inheritance in a domain model using JAXB:

@XmlElementRef used when you want to represent inheritance using the concept of an XML wildcard scheme:

XmlElements corresponds to the selection structure in the XML schema:


FULL EXAMPLE

The following is a complete example:

Mapping

 package forum7672121; import java.util.Collection; import javax.xml.bind.annotation.*; @XmlRootElement(name="something") @XmlAccessorType(XmlAccessType.FIELD) class Mapping{ @XmlElementWrapper(name="list") @XmlElement(name="item") Collection<A> list; } 

BUT

 package forum7672121; import javax.xml.bind.annotation.XmlSeeAlso; @XmlSeeAlso({B.class, C.class}) abstract class A{ } 

IN

 package forum7672121; class B extends A{ public String onlyB; } 

FROM

 package forum7672121; class C extends A{ public String onlyC; } 

Demo

 package forum7672121; import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Mapping.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum7672121/input.xml"); Mapping mapping = (Mapping) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(mapping, System.out); } } 

Input.xml / output

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <something> <list> <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="b"> <onlyB>b</onlyB> </item> <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="c"> <onlyC>c</onlyC> </item> </list> </something> 
+6
source

All Articles