XSD 根据属性值限制标签内容

XSD restrict tag content depending upon attribute value

我想定义一个 XSD 允许元素具有关于其属性值之一的特定 children。此属性值使用多个 xsd:enumeration.

定义

这是我的 XML 的样子:

<root>
    <Conversion type="Phys" />
    <Conversion type="Fact">
        <Factor>13</Factor>
        <Offset>37</Offset>
    </Conversion>
    <Conversion type="List">
        <Item>
            <Key>0</Key>
            <Value>KEY_0</Value>
        </Item>
        <Item>
            <Key>1</Key>
            <Value>KEY_1</Value>
        </Item>
    </Conversion>
</root>

到目前为止,我已经设法将 Conversion 标签限制为只有这 3 个属性和这 3 个序列,如 children (Factor/Offset ; Item 列表;无)。

这是我的一些 XSD :

<xs:element name="Conversion">
    <xs:complexType>
        <xs:choice>
            <xs:sequence>
                <xs:element name="Item" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Key" type="xs:decimal" />
                            <xs:element name="Value" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:sequence>
                <xs:element name="Factor" type="xs:double" />
                <xs:element name="Offset" type="xs:double" />
            </xs:sequence>
            <xs:sequence />
        </xs:choice>
        <xs:attribute name="Type">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="Fact" />
                    <xs:enumeration value="List" />
                    <xs:enumeration value="Phys" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
</xs:element>

我想做的是根据我的属性值限制children以避免禁止混合属性和内容。

您需要 XSD 1.1 才能完全按照您的要求进行操作,使内容模型依赖于属性的值。您可以使用条件类型分配甚至断言。

但是,如果您可以调整 XML 设计,则可以使用基本的 XSD 1.0(以及 XSD 1.1):

<root>
    <Phys/>
    <Fact>
        <Factor>13</Factor>
        <Offset>37</Offset>
    </Fact>
    <List>
        <Item>
            <Key>0</Key>
            <Value>KEY_0</Value>
        </Item>
        <Item>
            <Key>1</Key>
            <Value>KEY_1</Value>
        </Item>
    </List>
</root>

通常通过更具体的元素名称传达类型信息比通过使用类型属性扩充通用元素名称更好。