2011-10-26 2 views
6

Devo generare un elemento xml che può avere come valore qualsiasi "tipo primitivo" (xsd: string, xsd: booleano, ecc.). Esempi:JAXB - Imposta un XmlAdapter solo per un sottotipo specifico di un elemento?

<field xsi:type="xsd:string" name="aString">String Value</field> 
<field xsi:type="xsd:dateTime" name="aDate">2011-10-21</field> 
<field xsi:type="xsd:dateTime" name="aDateTime">2011-10-21T12:00:00</field> 
... 

Quindi, io uso questa implementazione che rende JAXB decidere il xsi:type del tipo primitivo:

public class Field { 
    @XmlAttribute 
    private String name; 

    @XmlElement 
    Object value; 
} 

e sta funzionando come previsto, ma tutto il java.util.Date Ottiene il tipo xs:dateTime ...

Ora voglio cambiare il comportamento del marshaller solo quando l'oggetto 'valore' è un esempio di java.util.Date per ottiene campi come questo:

<field xsi:type="xsd:date" name="aDate">2011-10-21</field> 
<field xsi:type="xsd:dateTime" name="aDateTime">2011-10-21T12:00:00</field> 

Quindi creare un adattatore, ma se provo questo:

@XmlElement 
@XmlJavaTypeAdapter(DateAdapter.class) 
Object value; 

Il mosto adattatore gestisce un tipo java.lang.Object

public class DateAdapter extends XmlAdapter<String, Object> {...} 

Ma io non voglio perdere la Marshaller JAXB per tutti gli altri oggetti (intero, doppio, ecc.) ...

c'è un modo per impostare un adattatore per un sottotipo specifico di un elemento?

+0

Hai trovato qualche soluzione per questo? – nhylated

+0

No davvero ... Ho un adattatore che gestisce la classe Object e gestisco internamente ogni sottotipo. Non è "bello", ma funziona. – ggarciao

risposta

-1

provare

http://jaxb.java.net/guide/Mapping_interfaces.html#Use__XmlJavaTypeAdapter

XmlJavaTypeAdapter per le interfacce con più implementazioni

+1

-1 Hai letto la domanda? Ho implementato un 'XmlAdapter ' ma con questo ho perso l'adattatore per 'Integer, Double, etc'. Quello che voglio è mantenere quegli adattatori, e ovviamente se uso un adattatore per oggetto la cosa più facile da fare è generare un 'xsi: anyType' ma questo è esattamente quello che non voglio – ggarciao

+0

Per quanto riguarda la soluzione" multiple implementations " , ciò implica che devo gestire e adattatore per 'Object' e implementare un wrapper per ogni sottoclasse di oggetti per generare il corretto' xsi: type'. Ancora una volta, qui sto perdendo gli adattatori che voglio mantenere. – ggarciao

0

ho affrontato una situazione simile se ero ritornassi dal XSD e generando le classi da lì. Detto questo, la soluzione dovrebbe essere trasferibile anche a voi.

Nei miei casi volevo estendere l'uso di una semplice stringa nel modello XSD in modo che emergesse come un UUID nel codice Java, quindi un altro sarebbe uscito come una classe in altri luoghi e così via. Lato XML, è tutto string (xs: string), quindi come ottenere tutte queste stringhe in tipi separati java side ...

Quello che ho finito di fare è, nell'XSD ho creato tipi semplici per ogni caso, qui il dichiarazione UUID:

e utilizzare questo invece di una stringa dovunque richiesto.

Ho quindi creato un file di bind in cui ho specificato i miei XmlAdaptor, proprio come hai fatto, tranne che ora ho obiettivi separati e quindi posso utilizzare più adattatori mirati specificamente a ciascun "tipo" xml.

Ora, avete una difficoltà aggiuntiva qui è che sul lato Java la rappresentazione del vostro campo è solo un oggetto. Suppongo che tu lo lanci una volta che conosci l'attributo type. Forse creando una sottoclasse di campi per ogni caso, questo ti permetterebbe di cambiare la dichiarazione di typeADaptor.