Questo è il mio scenario. Ho una classe generica:Campo duplicato in XML generato utilizzando JAXB
public class Tuple<T> extends ArrayList<T> {
//...
public Tuple(T ...members) {
this(Arrays.asList(members));
}
@XmlElementWrapper(name = "tuple")
@XmlElement(name = "value")
public List<T> getList() {
return this;
}
}
E una classe figlia:
public class StringTuple extends Tuple<String> {
public StringTuple(String ...members) {
super(members);
}
//explanation of why overriding this method soon ...
@XmlElementWrapper(name = "tuple")
@XmlElement(name = "value")
@Override
public List<String> getList() {
return this;
}
}
Queste classi si fa riferimento qui:
@XmlRootElement(namespace = "iv4e.xml.jaxb.model")
public class Relation {
private Tuple<StringTuple> relationVars;
//...
@XmlElementWrapper(name = "allRelationVars")
@XmlElement(name = "relationVarsList")
public Tuple<StringTuple> getRelationVars() {
return relationVars;
}
}
Poi un oggetto relazione viene creato con qualcosa di simile:
Relation rel = new Relation();
rel.setRelationVars(new Tuple<StringTuple>(
new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2")));
Dopo il marshalling questo oggetto, l'output XML è la seguente:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:relation xmlns:ns2="iv4e.xml.jaxb.model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="">
<allRelationVars>
<relationVarsList>
<tuple>
<value xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">RelationshipVar1</value>
</tuple>
<tuple>
<value>RelationshipVar1</value>
</tuple>
</relationVarsList>
<relationVarsList>
<tuple>
<value xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">RelationshipVar2</value>
</tuple>
<tuple>
<value>RelationshipVar2</value>
</tuple>
</relationVarsList>
</allRelationVars>
</ns2:relation>
Così i value
elementi sono duplicati !.
Ora, il motivo per lo StringTuple classe sostituisce List<T> getList()
con List<String> getList()
è di evitare i fastidiosi generati xmlns:xs
attributi in ogni membro della lista (gli value
elementi del documento XML). Ma poi ogni membro della lista viene mostrato due volte nell'output. Apparentemente, è perché sia il metodo genitore sovrascritto che il metodo figlio sono annotati con @XmlElement
. Quindi la mia domanda principale è: c'è un modo per ignorare i metodi sovrascritti annotati con @XmlElement
in Jaxb? (considerando che il metodo di overrideing è anche annotato con @XmlElement
)
Ho trovato un vecchio post che riportava un problema simile: http://old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html, ma non ho ancora trovato alcuna soluzione. Si noti inoltre che l'aggiunta di un'annotazione @XmlTransient
al metodo getList
nella classe genitore (Tuple<T>
) potrebbe risolvere questo problema, ma ne genererà altri, poiché la classe padre non è astratta e viene utilizzata da sola in altri contesti.
Una domanda secondaria a lato: è possibile dichiarare l'attributo xmlns:xs
al nodo radice invece di farlo - apparentemente - che appare in ogni nodo in cui è necessario? So che questo può essere fatto con la classe NamespacePrefixMapper
, ma poiché è una classe interna non standard, SUN, preferisco piuttosto usare un approccio più indipendente dall'implementazione.
Grazie in anticipo per qualsiasi feedback!
Prima di arrivare troppo lontano in questo problema, non gli oggetti del dominio hanno bisogno di estendere 'ArrayList'? Perché 'Tuple' estende 'ArrayList' invece di avere una proprietà di tipo' ArrayList'? –
Ciao Blaise !, ho scelto di ereditare da ArrayList poiché il mio oggetto Tuple è in realtà un ArrayList. Tuttavia, potrei conviverci con un ArrayList, anche se poi dovrei implementare alcuni metodi di delega. Ad ogni modo, questo non risolverà il mio problema poiché avrei ancora una classe generica Tuple e un StringTuple che estende la Tupla. –
Sergio
Ho aggiunto una risposta con un approccio che potrebbe essere utilizzato per sbarazzarsi della dichiarazione 'xsi: type'. –