2011-11-11 12 views
11

Voglio XML come questo:Come utilizzare JAXB @XmlValue in una sottoclasse?

<simple>Foo</simple> 

posso farlo con successo tramite una classe JAXB che assomiglia a questo:

@XmlRootElement(name="simple") 
class Simple { 
    @XmlValue 
    public String contents; 
} 

Ma ora ho bisogno di rendere la classe semplice essere una sottoclasse di un altro classe in questo modo:

@XmlRootElement(name="simple") 
class Simple extends OtherClass { 
    @XmlValue 
    public String contents; 
} 

che non riesce con @XmlValue is not allowed on a class that derives another class. non può facilmente refactoring la superclasse di distanza (a causa del modo in cui stiamo usando @XmlE lementRef su una classe wrapper). C'è una soluzione che mi consentirà di annotare la mia sottoclasse per generare quel semplice XML?

risposta

7

Nota: Sono in vantaggio EclipseLink JAXB (MOXy) e un membro del gruppo di esperti JAXB 2 (JSR-222).

Questo caso di utilizzo è supportato da Moxy, e IMHO dovrebbero essere sostenuti dal JAXB RI vedere:

semplice

Questa classe ha un campo mappato con @XmlValue ed estende OtherClass:

package forum809827; 

import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlValue; 

@XmlRootElement(name="simple") 
class Simple extends OtherClass { 

    @XmlValue 
    // @XmlValueExtension 
    // As of moxy 2.6, XmlValueExtension needs to be added for this to work 
    public String contents; 

} 

OtherClass

Questa è la super classe. Nel Moxy sottoclasse può mappare un campo/proprietà con @XmlValue fino a quando la super classe non ha mappature a un elemento XML:

package forum809827; 

import javax.xml.bind.annotation.XmlAttribute; 

public class OtherClass { 

    @XmlAttribute 
    public String other; 

} 

Demo

package forum809827; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Simple.class); 

     Simple simple = new Simple(); 
     simple.contents = "FOO"; 
     simple.other = "BAR"; 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.marshal(simple, System.out); 
    } 

} 

uscita

<?xml version="1.0" encoding="UTF-8"?> 
<simple xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" other="BAR">FOO</simple> 

Per ulteriori informazioni su Specifica MO Xy come vostro fornitore di JAXB

+0

Wow, grazie per l'esempio dettagliato! Sfortunatamente, il mio contenitore dell'app (Karaf) utilizza jaxb-impl/jaxb-xjc da ServiceMix e sarebbe difficile da cambiare, credo. –

+0

@ChrisDolan - Dipende dall'ambiente dell'applicazione. Il provider JAXB può essere configurato a livello di modello. Nel seguente post MOXy viene utilizzato nel server GlassFish che utilizza il RI JAXB per impostazione predefinita: http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-35.html –

+4

@ChrisDolan - quando si utilizza il JAXB RI si può essere in grado di marcare 'OtherClass' come @XmlTransient: http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html –

12

La risposta accettata non ha funzionato per me.

Tutto va bene, come descritto, ma ho anche bisogno di aggiungere il @XmlTransient alla superclasse

+0

Ho anche dovuto aggiungere '@XmlAccessorType (XmlAccessType.NONE)' al mio sottoclasse, o avrei ricevuto l'errore 'Se una classe ha la proprietà '@XmlElement', non può avere property.' '@XmlValue'. Spero che questo possa aiutare qualcuno. –

0

ero in grado di fare questo lavoro, modificando @XmlValue-@XmlMixed e cambiando la variabile a un elenco. La classe risultante dovrebbe apparire come la seguente.

@XmlRootElement(name="simple") 
class Simple extends OtherClass { 
    @XmlMixed 
    public List<String> contents; 
} 
0

Questo problema mi è successo e mi ha preso un po 'di tempo. Grazie a Blaise Doughan mi passano attraverso il suo blog e trova la risposta

  1. si deve aggiungere un file jaxb.properties con javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory nella stessa confezione, al fine di utilizzare Moxy

  2. add moxy alla vostra dipendenza Maven o aggiungere barattolo moxy

    <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.moxy</artifactId> <version>2.5.0</version> </dependency>

  3. poi tutti insieme ho campione qui si può andare anche se il mio progetto e dare un'occhiata a https://github.com/cicidi/HelloCCD/tree/master/Jaxb

Problemi correlati