多个XML元素到同一个类

时间:2015-09-29 13:22:44

标签: java xml jaxb

我想用JAXB做以下,但不知道,怎么做。我将首先向您展示一些代码,然后是详细信息。

@XmlRootElement(name = "root")
public class RootClass {    
    @XmlElementWrapper("foos")
    // ?? - I do not want to list here all my xml element 
    // types with @XmlElements({...})
    private List<Foo> fooList;    
}

public class Foo {    
    @XmlTransient
    // how to map the element's type (based on the xml element)
    // into this attribute?
    private FooType type;

    @XmlElement(name = "something", type = Something.class)
    private Something something;    
}

public class Baz extends Foo {
    @XmlElement(name = "somethingMore", type = SomethingMore.class)
    private SomethingMore more;
}

public enum FooType {
    BAR,
    QUX
}

XML结构:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="mynamespace"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="myschemalocation">

    <foos>
        <bar>
            <something ... />
        </bar>
        <qux>
            <something ... />
        </qux>
        <baz>
            <something ... />
            <somethingMore ... />
        </baz>
    </foos>
</root>

所以,我有上面的类和XML结构。几乎所有的Foo-s几乎都是相同的,但它们在FooType属性上有所不同。但是我的一些Foo-s非常不同:我想为它们创建一个新类(扩展原始的Foo)。在此示例中,此类称为Baz

使用JAXB,这可以解组这个结构吗?在这个例子的最后,我想得到一个RootClass对象,它有一个包含3个元素的列表:

  • 一个Foo对象,其类型为BAR
  • 一个Foo对象,其类型为QUX
  • 和一个Baz对象。

有可能,JAXB不知何故?我搜索了几个小时。我尝试使用@XmlRegistry@XmlElementDecl注释创建一个'ObjectFactory',但我不确定,该怎么做。

1 个答案:

答案 0 :(得分:0)

您可以根据以下两种可能之一使用XML架构。差异源于混合列表与三个同类列表序列形成对比的要求。

首先是混合清单:

<xsd:element name="root" type="RootType"/>
<xsd:complexType name="RootType">
  <xsd:choice maxOccurs="unbounded">
    <xsd:element name="bar" type="FooType"/>
    <xsd:element name="qux" type="FooType"/>
    <xsd:element name="baz" type="BazType"/>
  </xsd:choice>
</xsd:complexType>

这将导致(在类RootType中)

protected List<JAXBElement<? extends FooType>> barOrQuxOrBaz;

其中JAXBElement允许您提取标识元素的Qname(基本上是bar / qux / baz区别)和unmarshalled元素的POJO。

另一个变种并非如此混乱w.r.t.生成的API:

<xsd:element name="root" type="RootType"/>
<xsd:complexType name="RootType">
  <xsd:sequence>
    <xsd:element name="bar" type="FooType"
                 minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element name="qux"  maxOccurs="unbounded" type="FooType"
                 minOccurs="0" maxOccurs="unbounded"/>            
    <xsd:element name="baz" type="BazType"
                 minOccurs="0" maxOccurs="unbounded"/>     
  </xsd:sequence>
</xsd:complexType>

这将为您提供非常简单的

protected List<FooType> bar;
protected List<FooType> qux;
protected List<BazType> baz;