使用JAXB生成的XML中的重复字段

这是我的情景。 我有一个通用类:

public class Tuple extends ArrayList { //... public Tuple(T ...members) { this(Arrays.asList(members)); } @XmlElementWrapper(name = "tuple") @XmlElement(name = "value") public List getList() { return this; } } 

和一个儿童class:

 public class StringTuple extends Tuple { public StringTuple(String ...members) { super(members); } //explanation of why overriding this method soon ... @XmlElementWrapper(name = "tuple") @XmlElement(name = "value") @Override public List getList() { return this; } } 

这里引用了这些类:

 @XmlRootElement(namespace = "iv4e.xml.jaxb.model") public class Relation { private Tuple relationVars; //... @XmlElementWrapper(name = "allRelationVars") @XmlElement(name = "relationVarsList") public Tuple getRelationVars() { return relationVars; } } 

然后使用以下内容创建Relation对象:

 Relation rel = new Relation(); rel.setRelationVars(new Tuple( new StringTuple("RelationshipVar1"), new StringTuple("RelationshipVar2"))); 

编组此对象后,Xml输出如下:

      RelationshipVar1   RelationshipVar1     RelationshipVar2   RelationshipVar2     

所以value元素是重复的!

现在,类StringTuple用List getList()覆盖List getList()的原因是避免在列表的每个成员(xml文档中的value元素)中生成恼人的xmlns:xs属性。 但是然后列表中的每个成员在输出中显示两次。 显然,这是因为重写的父方法和子方法都使用@XmlElement注释。 所以我的主要问题是:有一种方法可以忽略在Jaxb中用@XmlElement注释的重写方法吗? (考虑到覆盖方法也用@XmlElement注释)

我发现一个旧post报告了类似的问题: http : //old.nabble.com/@XmlElement-on-overridden-methods-td19101616.html ,但我还没有找到任何解决方案。 另请注意,在父类( Tuple )的getList方法中添加@XmlTransient注释可以解决此问题,但会生成其他问题,因为父类不是抽象的,并且在其他上下文中单独使用。

一方面的第二个问题:是否可以在根节点声明xmlns:xs属性而不是它 – 令人不快 – 出现在需要它的每个节点中? 我知道这可以使用NamespacePrefixMapper类完成,但由于它是一个非标准的SUN内部类,我宁愿使用更多独立于实现的方法。

提前感谢您的任何反馈!

您可以使用以下方法在父@XmlTransient上标记属性@XmlTransient ,在子@XmlTransient上标记@XmlElement

 package forum7851052; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; @XmlRootElement public class Parent { private List item = new ArrayList(); @XmlTransient public List getItem() { return item; } public void setItem(List item) { this.item = item; } } 

IntegerChild

 package forum7851052; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class IntegerChild extends Parent { @Override @XmlElement public List getItem() { return super.getItem(); } @Override public void setItem(List item) { super.setItem(item); } } 

StringChild

 package forum7851052; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class StringChild extends Parent { @Override @XmlElement public List getItem() { return super.getItem(); } @Override public void setItem(List item) { super.setItem(item); } } 

演示

 package forum7851052; 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(Parent.class, IntegerChild.class, StringChild.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); IntegerChild integerChild = new IntegerChild(); integerChild.getItem().add(1); integerChild.getItem().add(2); marshaller.marshal(integerChild, System.out); StringChild stringChild = new StringChild(); stringChild.getItem().add("A"); stringChild.getItem().add("B"); marshaller.marshal(stringChild, System.out); } } 

产量

   1 2    A B  

这可能很旧,但它是搜索“JAXB重复字段”时的第一个结果

偶然发现同样的问题,这对我有用:

 @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) // <-- made the difference public abstract class ParentClass { ... } @XmlRootElement public class ChildClass extends ParentClass { ... }