使用JAXB并根据封闭标记以不同方式解释相同的标记

时间:2014-08-13 19:38:27

标签: java xml jaxb unmarshalling

在下面的示例中,A中的Data块和B中的Data块应该被解组到不同的类中。这是使用JAXB实现的吗?

<Content>
  <A>
    <Data>
      <Name></Name>
      <Age></Age>
    </Data>
  </A>
  <B>
    <Data>
      <MobilePhone></MobilePhone>
      <WorkPhone></WorkPhone>
    </Data>
  </B>
</Content>

A中的数据和B内的数据代表不同的类.A中的数据应映射到AData.class,B中的数据应映射到BData.class。

注意:编组工作正常。任意数量的类都可以具有相同的名称标记。生成的xml包含所有这些类的相同标记。在这种情况下,AData和BData都将作为&lt; Data&gt;写入XML。 。但即使是相同的编组xml也无法再解组。我希望通过添加一些额外的注释来解决这个问题。

2 个答案:

答案 0 :(得分:0)

您只需要具备以下条件:

@XmlAccessorType(XmlAccessType.FIELD)
public class A {

    @XmlElement(name="Data")
    private AData data;

}
@XmlAccessorType(XmlAccessType.FIELD)
public class B {

    @XmlElement(name="Data")
    private BData data;

}
@XmlRootElement(name="Content")
@XmlAccessorType(XmlAccessType.FIELD)
public class Content {

    @XmlElement(name="A")
    private A a;

    @XmlElement(name="B")
    private B b;

}

答案 1 :(得分:0)

如果您事先知道内容将包含的对象,Blaise发布的解决方案将是解决此问题的好方法,例如:

public class Content {

    @XmlElement(name="A")
    private A a;

    @XmlElement(name="B")
    private B b;

}

但另一种方法是将内容中包含的数据包含在A / B扩展的某些超类型列表中,这样就可以得到如下所示的XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Content>
    <myContent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="a">
        <Data>
            <Name>Joe Smith</Name>
            <Age>25</Age>
        </Data>
    </myContent>
    <myContent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="b">
        <Data>
            <MobilePhone>555-234-5678</MobilePhone>
            <WorkPhone>555-555-5555</WorkPhone>
        </Data>
    </myContent>
</Content>

你可以通过这样注释你的类来获得这个:

@XmlRootElement(name = "Content")
@XmlAccessorType(XmlAccessType.FIELD)
public class Content {
    @XmlElement
    List<SomeSuperType> myContent;

    public Content() {

    }

    public List<SomeSuperType> getMyContent() { return this.myContent; }
    public void setMyContent(List<SomeSuperType> myContent ) { this.myContent = myContent; }
}

// class for A
@XmlRootElement(name = "A")
@XmlAccessorType(XmlAccessType.FIELD)
public class A extends SomeSuperType {
    @XmlElement(name="Data")
    AData data;

    public A() {
        data = new AData();
    }

    public void setName(String name) {
        data.name = name;
    }
    public void setAge(int age) {
        data.age = age;
    }

    public String getName() { return data.name; }
    public int getAge() { return data.age; }
}

class AData {
    @XmlElement(name = "Name")
    String name;
    @XmlElement(name = "Age")
    int age;
}


// class for B
@XmlRootElement(name = "B")
@XmlAccessorType(XmlAccessType.FIELD)
public class B extends SomeSuperType {
    @XmlElement(name = "Data")
    BData data;

    public B() {
        data = new BData();
    }

    public void setMobilePhone(String mobilePhone) { data.mobilePhone = mobilePhone; }
    public void setWorkPhone(String workPhone) { data.workPhone = workPhone; }
    public String getMobilePhone() { return data.mobilePhone; }
    public String getWorkPhone() { return data.workPhone; }
}

class BData {
    @XmlElement(name="MobilePhone")
    String mobilePhone;
    @XmlElement(name="WorkPhone")
    String workPhone;
    public BData() {

    }
}