2011-02-03 17 views
6

Ho una gerarchia di classi generate da JAXB. Vorrei effettuare il marshalling di una classe figlio come elemento della classe base (ma con tutti gli attributi della classe figlio), usando xsi: type per indicare il tipo concreto.JAXB Marshalling e polimorfismo

Ad esempio, dato un animale e una sottoclasse uccello:

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

Non importa quanto mi maresciallo un uccello, per esempio:

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

Il risultato è sempre un elemento di uccello:

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

Tuttavia, ciò che voglio è questo (tutti gli attributi di sottoclasse, tipo xsi, nome elemento della classe base):

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

Cosa c'è di strano è che se creo un elemento di involucro:

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

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

e il maresciallo che, utilizza il tipo di classe di base:

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

Se io costruisco manualmente il mio XML desiderato documento, JAXB non ha problemi a smantellarlo. Come posso creare il mio schema XML e/o configurare JAXB per consentire il mio comportamento di marshalling desiderato?

Grazie.

risposta

1

Si potrebbe fare la seguente:

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

Partenza:

+0

Grazie. Il tuo esempio ha un wrapper attorno agli oggetti che sono polimorfici, come il mio esempio di AnimalWrapper, e non è quello che sto cercando. Voglio il polimorfismo all'elemento radice. – SingleShot

+0

Ho aggiornato la mia risposta per risolvere il caso root. –

+0

Grazie. L'animale è astratto quindi non posso proprio farlo. Potrei sciogliere lo schema, suppongo, ma preferisco non farlo. Giocherò con cose simili a ciò che suggerisci. – SingleShot

Problemi correlati