JAXB Marshalling and Polymorphism

I have a hierarchy of classes created by JAXB. I would like to march the child class as an element of the base class (but with all the attributes of the child class), using xsi: type to indicate the specific type.

For example, given the subclass Animal and Bird:

<xs:complexType name="animal" abstract="true"> <xs:sequence> <xs:element name="name" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="bird"> <xs:complexContent> <xs:extension base="animal"> <xs:sequence> <xs:element name="maxAltitude" type="xs:int"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="Animal" type="animal"/> <xs:element name="Bird" type="bird"/> 

No matter how I marshal the Bird, for example:

 Bird sparrow = new Bird(); sparrow.setName("Sparrow"); sparrow.setMaxAltitude(1000); JAXBContext context = JAXBContext.newInstance(Animal.class, Bird.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(sparrow, System.out); 

As a result, there is always a Bird element:

 <Bird xmlns="http://mycompany.com/animals"> <name>Sparrow</name> <maxAltitude>1000</maxAltitude> </Bird> 

However, I want this (all attributes of the subclass, type xsi, element name of the base class):

 <Animal xmlns="http://mycompany.com/animals" xsi:type="bird" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <name>Sparrow</name> <maxAltitude>1000</maxAltitude> </Animal> 

Which is strange if I create a shell element:

 <xs:complexType name="animalWrapper"> <xs:sequence> <xs:element name="Animal" type="animal"/> </xs:sequence> </xs:complexType> <xs:element name="AnimalWrapper" type="animalWrapper"/> 

and marshal it, it uses the base class type:

 <AnimalWrapper xmlns="http://mycompany.com/animals" <Animal xsi:type="bird" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <name>Sparrow</name> <maxAltitude>1000</maxAltitude> </Animal> </AnimalWrapper> 

If I manually create my desired XML document, JAXB has no problem canceling it. How can I create an XML schema and / or configure JAXB to allow my desired marshalling behavior?

Thanks.

+6
java polymorphism xsd jaxb
source share
1 answer

You can do the following:

 QName qName = jc.createJAXBIntrospector().getElementName(new Animal()); JAXBElement<Animal> jaxbElement = new JAXBElement<Animal>(qName, Animal.class, new Bird()); marshaller.marshal(jaxbElement, System.out); 

Departure:

+1
source share

All Articles