JAXB Маршаллинг и Полиморфизм - PullRequest
6 голосов
/ 03 февраля 2011

У меня есть иерархия сгенерированных JAXB классов.Я хотел бы маршалировать дочерний класс как элемент базового класса (но со всеми атрибутами дочернего класса), используя xsi: type для обозначения конкретного типа.

Например, учитывая подкласс Animal и 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"/>

Независимо от того, как я собираю Птицу, например:

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);

Результатом всегда является элемент Птица:

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

Однако, что я хочуэто (все атрибуты подкласса, типа xsi, имени элемента базового класса):

<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>

Странно, что если я создаю элемент-обертку:

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

<xs:element name="AnimalWrapper" type="animalWrapper"/>

и маршалю его,он использует тип базового класса:

<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>

Если я вручную создаю желаемый XML-документ, у JAXB не возникает проблем с его демонтажем.Как я могу создать свою XML-схему и / или настроить JAXB для разрешения желаемого поведения при сортировке?

Спасибо.

1 Ответ

1 голос
/ 03 февраля 2011

Вы можете сделать следующее:

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

Выезд:

...