这是我的场景。我有一个泛型类:
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;
}
}
和一个子类:
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;
}
}
此处引用这些类:
@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;
}
}
然后使用类似以下内容创建 Relation 对象:
Relation rel = new Relation();
rel.setRelationVars(new Tuple<StringTuple>(
new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2")));
编组此对象后,Xml 输出如下:
<?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>
因此 value
元素是重复的!
现在,类 StringTuple 重写 List 的原因是getList()
和 List; getList()
避免了列表中每个成员(xml 文档中的 value
元素)中生成的烦人的 xmlns:xs
属性。
但是列表中的每个成员都会在输出中显示两次。显然,这是因为重写的父方法和子方法都用@XmlElement
注释。
所以我的主要问题是:有一种方法可以忽略 Jaxb 中用 @XmlElement
注释的重写方法吗? (考虑到覆盖方法也用 @XmlElement
进行注释)
我发现一个旧帖子报告了非常相似的问题:http://old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html ,但我还没有找到任何解决方案。
另请注意,向父类 (Tuple
) 的 getList
方法添加 @XmlTransient
注释可以解决此问题,但会生成其他,因为父类不是抽象的并且在其他上下文中单独使用。
一方面的次要问题:是否可以在根节点声明 xmlns:xs 属性,而不是令人厌烦地出现在需要它的每个节点中?我知道这可以使用 NamespacePrefixMapper
类来完成,但由于它是一个非标准的 SUN 内部类,所以我更喜欢使用更独立于实现的方法。
预先感谢您的任何反馈!
This is my scenario. I have a generic class:
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;
}
}
And a child class:
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;
}
}
These classes are referenced here:
@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;
}
}
Then a Relation object is created with something like:
Relation rel = new Relation();
rel.setRelationVars(new Tuple<StringTuple>(
new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2")));
After marshalling this object, the Xml output is the following:
<?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>
So the value
elements are duplicated!.
Now, the reason the class StringTuple overrides List<T> getList()
with List<String> getList()
is avoiding the annoying generated xmlns:xs
attributes in every member of the list (the value
elements in the xml document).
But then every member of the list is shown twice in the output. Apparently, it is because both the overridden parent method and the child method are annotated with @XmlElement
.
So my main question is: there is a way to ignore overridden methods annotated with @XmlElement
in Jaxb ? (considering that the overridding method is also annotated with @XmlElement
)
I found an old post reporting quite a similar problem: http://old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html , but I have not found any solution yet.
Also note that adding a @XmlTransient
annotation to the getList
method at the parent class (Tuple<T>
) could solve this problem but will generate others, since the parent class is not abstract and is used alone in other contexts.
One side secondary question: is it possible to declare the xmlns:xs
attribute at the root node instead of it -annoyingly- appearing in every node where it is needed? I know this can be done with the NamespacePrefixMapper
class, but since it is a non standard, SUN internal class, I rather prefer to use a more implementation independent approach.
Thanks in advance for any feedback !
发布评论
评论(2)
这可能很旧,但它是搜索“JAXB重复字段”时的第一个结果
偶然发现了同样的问题,这对我来说是成功的:
This might be quite old, but its the first result while searching for "JAXB duplicate fields"
Stumbled upon the same problem, this did the trick for me:
您可以使用以下方法在父级上标记属性
@XmlTransient
并在子级上标记@XmlElement
:Parent
IntegerChild
StringChild
演示
输出
You could use the following approach of marking the property
@XmlTransient
on the parent and@XmlElement
on the child:Parent
IntegerChild
StringChild
Demo
Output