使用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 { ... }