有没有办法让派生类型在 XML 模式中为其父元素赋值?

Is there a way for a derived type to assign a value to its parent's element in XML Schema?

假设我有以下架构:

<xs:schema targetNamespace="animals" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="animals">

<xs:complexType name="AnimalType" abstract="true">
    <xs:sequence>
        <xs:element name="legs" xml:base="xs:nonNegativeInteger"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="DogType">
    <xs:complexContent>
        <xs:extension base="AnimalType">
            <xs:sequence>
                <xs:element name="furColor" xml:base="xs:string"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="BirdType">
    <xs:complexContent>
        <xs:extension base="AnimalType">
            <xs:sequence>
                <xs:element name="canFly" xml:base="xs:boolean"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

</xs:schema>

让我们假设所有的狗都有 4 条腿,所有的鸟都有 2 条腿。是否可以将这些值设置为默认值,以便可以在不指定它们的情况下创建元素?

<!--a black dog with 4 legs-->
<dog>
    <furColor>black</furColor>
</dog>

<!--a flightless bird with 2 legs-->
<bird>
    <canFly>false</canFly>
</bird>

如果不是,是否至少可以修改父元素的限制,以创建例如五足狗不可能吗?

我认为不可能有一个隐含的默认 元素 legs。但是可以修改使五足狗无效的类型,方法是先针对 legs 限制 AnimalType,然后扩展该受限类型:

<xs:complexType name="AnimalType" abstract="true">
    <xs:sequence>
        <xs:element name="legs" type="xs:nonNegativeInteger"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="AnimalWith2LegsType" abstract="true">
    <xs:complexContent>
        <xs:restriction base="AnimalType">
            <xs:sequence>
                <xs:element name="legs">
                    <xs:simpleType>
                        <xs:restriction base="xs:nonNegativeInteger">
                            <xs:enumeration value="2"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="AnimalWith4LegsType" abstract="true">
    <xs:complexContent>
        <xs:restriction base="AnimalType">
            <xs:sequence>
                <xs:element name="legs">
                    <xs:simpleType>
                        <xs:restriction base="xs:nonNegativeInteger">
                            <xs:enumeration value="4"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="DogType">
    <xs:complexContent>
        <xs:extension base="AnimalWith4LegsType">
            <xs:sequence>
                <xs:element name="furColor" type="xs:string"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="BirdType">
    <xs:complexContent>
        <xs:extension base="AnimalWith2LegsType">
            <xs:sequence>
                <xs:element name="canFly" type="xs:boolean"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:element name="animals">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="dog" type="DogType"/>
            <xs:element name="bird" type="BirdType"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

这种模式的实例被强制指定具有指定固定值的 legs 元素:

<dog>
    <legs>4</legs>
    <furColor>black</furColor>
</dog>

<bird>
    <legs>2</legs>
    <canFly>false</canFly>
</bird>

如果 legs 被指定为 属性 确实可以有一个隐含的边数。只需将 AnimalTypeAnimalWith2LegsTypeAnimalWith4LegsType 的定义更改为:

<xs:complexType name="AnimalType" abstract="true">
    <xs:sequence>
    </xs:sequence>
    <xs:attribute name="legs" type="xs:nonNegativeInteger"/>
</xs:complexType>

<xs:complexType name="AnimalWith2LegsType" abstract="true">
    <xs:complexContent>
        <xs:restriction base="AnimalType">
            <xs:sequence>
            </xs:sequence>
            <xs:attribute name="legs" type="xs:nonNegativeInteger" fixed="2" use="optional"/>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="AnimalWith4LegsType" abstract="true">
    <xs:complexContent>
        <xs:restriction base="AnimalType">
            <xs:sequence>
            </xs:sequence>
            <xs:attribute name="legs" type="xs:nonNegativeInteger" fixed="4" use="optional"/>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

现在您可以拥有包含以下内容的有效实例:

<dog legs="4">
    <furColor>black</furColor>
</dog>

<bird legs="2">
    <canFly>false</canFly>
</bird>

<dog>
    <furColor>black</furColor>
</dog>

<bird>
    <canFly>false</canFly>
</bird>

除非您不打算指定多组腿(也许是 caterpillars?),否则您需要将 legs 建模为属性来实现您想要的。