使用JAXB生成的XML中的重复字段 [英] Duplicated field in generated XML using JAXB

查看:131
本文介绍了使用JAXB生成的XML中的重复字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的方案。我有一个泛型类:

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;
  }
}

儿童班:

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对象: / p>

Then a Relation object is created with something like:

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

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

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>

所以元素是重复的!

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

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)

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

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.

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

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 !

推荐答案

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

You could use the following approach of marking the property @XmlTransient on the parent and @XmlElement on the child:

父母

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<T> {

    private List<T> item = new ArrayList<T>();

    @XmlTransient
    public List<T> getItem() {
        return item;
    }

    public void setItem(List<T> 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<Integer> {

    @Override
    @XmlElement
    public List<Integer> getItem() {
        return super.getItem();
    }

    @Override
    public void setItem(List<Integer> 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<String> {

    @Override
    @XmlElement
    public List<String> getItem() {
        return super.getItem();
    }

    @Override
    public void setItem(List<String> 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);
    }

}

输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<integerChild>
    <item>1</item>
    <item>2</item>
</integerChild>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<stringChild>
    <item>A</item>
    <item>B</item>
</stringChild>

这篇关于使用JAXB生成的XML中的重复字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆