jaxb:防止创建冗余集合?

时间:2018-08-03 11:33:54

标签: java xml jaxb

我正在使用JAXB来生成用于解析XML文件的Java代码,并且只要XML中可能重复出现某个元素,生成的类都会通过一个单独的类中的集合包含额外的间接级别,这对我和使使用这些类的代码不太雅致。为了说明我的意思,假设我的XML文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <columns>
        <column id="c1">
            <order>1</order>
            <name>first</name>
            <type>text</type>
        </column>

        <column id="c2">
            <order>2</order>
            <name>second</name>
            <type>text</type>
        </column>

        <column id="c3">
            <order>3</order>
            <name>third</name>
            <type>text</type>
        </column>
    </column>
</columns>

和这样的模式:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="configuration" type="Configuration"/>

    <xs:complexType name="ColumnList">
        <xs:sequence>
            <xs:element type="Column" name="column" maxOccurs="unbounded" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Column">
        <xs:sequence>
            <xs:element type="xs:integer" name="order"/>
            <xs:element type="xs:string" name="name"/>
            <xs:element name="type">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="text"/>
                        <xs:enumeration value="number"/>
                        <xs:enumeration value="date"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element type="xs:string" name="format" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute type="xs:string" name="id"/>
        <xs:attribute type="xs:boolean" name="optional" use="optional"/>
    </xs:complexType>
</xs:schema>

现在,如果我让JAXB生成我的类,我会得到一个看起来像这样的类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Configuration", propOrder = {
    "columns",
    "providers"
})
public class Configuration {
    @XmlElement(required = true)
    protected ColumnList columns;
    // ...
}

ColumnList只是

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ColumnList", propOrder = {
    "column"
})
public class ColumnList {
    protected List<Column> column;
    // ...
}

由于我总是必须做类似config.getColumns().getColumn()的事情,因此访问列比较麻烦。

所以我的问题是:有什么办法可以让JAXB忽略这种额外的间接级别?与其创建仅包含ColumnList的{​​{1}}类型,不如不只在List<Column>类中使用List<Column>,而是可以编写Configuration

模式定义在我的控制之下,因此更改它没有问题,但是我怀疑仅凭此定义是不够的。我怀疑指定显式的JAXB绑定可能可以解决问题,但是我不确定如何做到这一点。

1 个答案:

答案 0 :(得分:0)

您可以省略ColumnList类型,并指定Configuration以包含名为{em> columns 的Column个元素的集合。
生成的代码将不再具有ColumnList类或额外的间接级别。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="configuration" type="Configuration">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="Column" name="columns" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="Column">
        <xs:sequence>
            <xs:element type="xs:integer" name="order"/>
            <xs:element type="xs:string" name="name"/>
            <xs:element name="type">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="text"/>
                        <xs:enumeration value="number"/>
                        <xs:enumeration value="date"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element type="xs:string" name="format" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute type="xs:string" name="id"/>
        <xs:attribute type="xs:boolean" name="optional" use="optional"/>
    </xs:complexType>
</xs:schema>