如何引用 xml 架构中的所有扩展类型?

How to refer to all extended types in xml schema?

在我的 XML 模式文件中,我有以下具有一些属性的基本类型:

<xs:complexType name="block">
    <xs:attribute name="blockid" type="xs:integer" use="required"/>
    <xs:attribute name="x" type="xs:integer" use="required"/>
    <xs:attribute name="y" type="xs:integer" use="required"/>
</xs:complexType>

以及通过扩展它获得的其他几种类型,以允许附加属性或子元素:

<xs:complexType name="wall">
    <xs:complexContent>
        <xs:extension base="block">
            <xs:attribute name="width" type="xs:integer" use="required"/>
            <xs:attribute name="height" type="xs:integer" use="required"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="key">
    <xs:complexContent>
        <xs:extension base="block">
            <xs:sequence maxOccurs="unbounded">
                <xs:element name="keyid" type="xs:integer"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

和其他人。

现在我想定义一个元素,它可以将任何这些扩展类型作为子元素,但不能包含基本类型。
我现在可以执行以下操作:

<xs:complexType name="room">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="wall" type="wall"/>
        <xs:element name="key" type="key"/>
        <xs:element .../>
        and so on for each extended type
    </xs:choice>
</xs:complexType>

但是,由于将来我可能会添加其他扩展类型,并且它们都可以是房间元素的子元素类型,有没有办法告诉允许从块扩展的任何类型而不是提及一一扩展类型?
我不想引用它们中的每一个,而是想做类似的事情:

<xs:complexType name="room">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="whatever" type="any type extended from block"/>
    </xs:choice>
</xs:complexType>

我建议在这里使用替换组。

<xs:element name="block" abstract="true" type="block"/>

<xs:element name="wall" substitutionGroup="block">
  <xs:complexType>
    <xs:complexContent>
        <xs:extension base="block">
            <xs:attribute name="width" type="xs:integer" use="required"/>
            <xs:attribute name="height" type="xs:integer" use="required"/>
        </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

<xs:complexType name="room">
    <xs:sequence>
        <xs:element ref="block" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>