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

时间:2016-06-03 13:15:59

标签: xml xsd xsd-validation xml-validation

我想定义一个允许元素具有关于其属性值之一的特定子元素的XSD。此属性值使用多个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个序列作为子代(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>

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

1 个答案:

答案 0 :(得分:2)

您需要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>

类型信息通常通过更具体的元素名称传递,而不是通过使用type属性扩充通用元素名称。