声明XSD中各种类型的集合

时间:2019-02-08 10:13:20

标签: java xml xsd jaxb

我有一个API,该API返回一组XML对象,这些对象保证可以由抽象类表示,但是由于它们采用以下形式,因此不能直接作为列表访问:

    for(j = size_phrase -1 ; j >= 0 ; j-- , k++)

由于公司的惯例,我将使用XSD编写此提要的模型,XSD由JaxB解析以生成源文件。但是,由于没有单独将Types声明为集合的可能元素(出于明显的原因,我不想这样做),所以我不知道该如何处理并将响应的子元素作为单个集合来获取。

响应的XSD。

<Response Timestamp="2019-02-06T13:16:32">
    <TypeA [xml attributes]...>
        ...
    </TypeA>
    <TypeB ...>
        ...
    </TypeB>
    ... (Different repeating elements)
</Response>

示例元素类型

<xs:complexType name="Response">
    <xs:sequence>
        <xs:element name="Types" type="model:AbstractType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

如何在XSD中指定任何扩展了AbstractType的TypeX对象都应从响应中放入Ty​​pes集合中?

很高兴提供任何必要的进一步信息,只要我不允许与他人分享。

看到了this相关的问题,但是它接受了任何元素,并且限制是基于名称的,为此,我理想地希望验证收集到的元素是有效的TypeX对象。

1 个答案:

答案 0 :(得分:1)

假设您已将每个TypeX定义为XSD中的AbstractType扩展名:

<xsd:complexType name="TypeX">
        <xsd:complexContent>
            <xsd:extension base="AbstractType">
                ...
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

那么您可以做:

1)XSD选项,如果您确实要为每个TypeX使用不同的XML元素名称(不建议这样做,因为每次添加新的AbstractType子类型时都需要修改Response类型):

<xs:complexType name="Response">
    <xs:choice maxOccurs="unbounded">
        <xs:element name="typeA" type="model:TypeA" />
        <xs:element name="typeB" type="model:TypeB" />
    </xs:sequence>
</xs:complexType>

2)XML多态性(接近您的建议),尽管更改了XML形式,但更加通用:

<xs:complexType name="Response">
    <xs:sequence>
        <xs:element name="something" type="model:AbstractType" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
</xs:complexType>

(用一些有意义的名称替换“某物”,具体取决于AbstractType实际代表什么。)

xml看起来像这样:

<Response Timestamp="2019-02-06T13:16:32" xmlns="...">
    <something xsi:type="TypeA" [xml attributes]...>
        ...
    </something>
    <something xsi:type="TypeB" ...>
        ...
    </something>
    ... (Different repeating elements)
</Response>

在两种情况下,建议您使用JAXB RI extension for simpler/better binding mode(第3.1.6节)或等效扩展名,以简化生成的代码并在必要时将生成的字段转换为复数形式。

然后在Response类中生成代码(注意复数形式): List<AbstractType> somethings;