Esta es mi situación. Tengo una clase genérica:Campo duplicado en XML generado utilizando 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;
}
}
Y una clase hija:
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;
}
}
se hace referencia a estas clases aquí:
@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;
}
}
A continuación, un objeto Relation se crea con algo como:
Relation rel = new Relation();
rel.setRelationVars(new Tuple<StringTuple>(
new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2")));
Después de ordenar este objeto, la salida XML es el siguiente:
<?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>
Así que los elementos están duplicados value
!.
Ahora, la razón por la StringTuple clase anula List<T> getList()
con List<String> getList()
es evitar los molestos generados xmlns:xs
atributos de todos los miembros de la lista (los value
elementos del documento XML). Pero luego cada miembro de la lista se muestra dos veces en la salida. Aparentemente, es porque tanto el método padre anulado como el método secundario están anotados con @XmlElement
. Así que mi pregunta principal es: ¿hay una forma de ignorar los métodos anotados anotados con @XmlElement
en Jaxb? (teniendo en cuenta que el método de anulación también está anotado con @XmlElement
)
Encontré una publicación anterior que informaba sobre un problema bastante similar: http://old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html, pero no encontré ninguna solución todavía. También tenga en cuenta que agregar una anotación @XmlTransient
al método getList
en la clase principal (Tuple<T>
) podría resolver este problema pero generará otros, ya que la clase padre no es abstracta y se usa sola en otros contextos.
Pregunta secundaria de un lado: ¿es posible declarar el atributo xmlns:xs
en el nodo raíz en lugar de mostrarlo -annoyingly- en cada nodo donde se necesita? Sé que esto se puede hacer con la clase NamespacePrefixMapper
, pero como es una clase interna SUN no estándar, prefiero usar un enfoque más independiente de la implementación.
¡Gracias de antemano por cualquier comentario!
Antes de llegar demasiado lejos en este problema, sus objetos de dominio necesitan extender 'ArrayList'? ¿Por qué 'Tuple' extiende' ArrayList' en lugar de tener una propiedad de tipo 'ArrayList'? –
¡Hola, Blaise !, elegí heredar de ArrayList ya que mi objeto Tuple es, de hecho, una ArrayList. Sin embargo, podría vivir con un ArrayList en su lugar, aunque tendría que implementar algunos métodos de delegación. De todos modos, eso no resolvería mi problema, ya que todavía tendría una clase genérica Tuple y un StringTuple extendiendo Tuple. –
Sergio
He agregado una respuesta con un enfoque que podría usarse para deshacerse de la declaración 'xsi: type'. –