XSD 根据属性值限制元素的内容

XSD restrict content of element depending on attributes value

正式我们的 XSD 看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="fooxsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

  <xs:element name="List">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Config" type="ConfigType" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="Entry">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute name="key" type="xs:ID" use="required" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

</xs:schema>

XMLs 可以是这样的:

<?xml version="1.0" encoding="utf-8"?>
<List xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd">
  <Entry key="foo">bar</Config>
  <Entry key="baz">boom</Config>
</List>

只有一个键值列表。

现在我有一个这样的约束列表:

我想将此列表放入 XSD,因此 XML-作者不能输入未定义的键或该键不允许的值。

我知道去掉 key-attribute 会更好,像

<List>
  <foo>bar</foo>
  <baz>boom</foo>
</List>

可惜我做不到;格式必须保持不变。但是有更多的限制。我必须根据键属性中给出的内容来限制内容。

我读了

此处在第二个答案中提到了 元素 - 这可能是一个解决方案。虽然丑陋,但也许有更好的使用通常的 xsd-elements?

在 XML Schema 1.1 中,xs:alternative 可以指定 attribute-dependent 类型,如您的 link ().

所示

对于您的示例,架构可能如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xsv="http://www.w3.org/2007/XMLSchema-versioning"
           elementFormDefault="qualified"
           xsv:minVersion="1.1">

  <xs:element name="List">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Config" minOccurs="0" maxOccurs="unbounded">
          <xs:alternative test="@key='foo'" type="ConfigKeyFooType"/>
          <xs:alternative test="@key='baz'" type="ConfigKeyBazType"/>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:attributeGroup name="ConfigTypeAttributeGroup">
    <xs:attribute name="key" type="xs:ID" use="required" />
  </xs:attributeGroup>

  <xs:complexType name="ConfigKeyFooType">
    <xs:simpleContent>
      <xs:extension base="ConfigKeyFooContentType">
        <xs:attributeGroup ref="ConfigTypeAttributeGroup"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:simpleType name="ConfigKeyFooContentType">
    <xs:restriction base="xs:NMTOKEN">
      <xs:enumeration value="bar"/>
      <xs:enumeration value="bar2"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="ConfigKeyBazType">
    <xs:simpleContent>
      <xs:extension base="ConfigKeyBazContentType">
        <xs:attributeGroup ref="ConfigTypeAttributeGroup"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:simpleType name="ConfigKeyBazContentType">
    <xs:restriction base="xs:NMTOKEN">
      <xs:enumeration value="boom"/>
      <xs:enumeration value="box"/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

有效xml…

<?xml version="1.0" encoding="utf-8"?>
<List>
  <Config key="foo">bar</Config>
  <Config key="baz">boom</Config>
</List>

…被评估为有效。

无效 xml 由于重复键…

<?xml version="1.0" encoding="utf-8"?>
<List>
  <Config key="foo">bar</Config>
  <Config key="baz">boom</Config>
  <Config key="foo">bar2</Config>
  <Config key="baz">box</Config>
</List>

…被评估为无效消息:

[Error] sample-bad-dup-keys.xml:5:21:cvc-id.2: There are multiple occurrences of ID value 'foo'.
[Error] sample-bad-dup-keys.xml:5:21:cvc-attribute.3: The value 'foo' of attribute 'key' on element 'Config' is not valid with respect to its type, 'ID'.
[Error] sample-bad-dup-keys.xml:6:21:cvc-id.2: There are multiple occurrences of ID value 'baz'.
[Error] sample-bad-dup-keys.xml:6:21:cvc-attribute.3: The value 'baz' of attribute 'key' on element 'Config' is not valid with respect to its type, 'ID'.

无效 xml 由于无效值…

<?xml version="1.0" encoding="utf-8"?>
<List>
  <Config key="foo">bar3</Config>
  <Config key="baz">boox</Config>
</List>

…被评估为无效消息:

[Error] sample-bad-values.xml:3:34:cvc-enumeration-valid: Value 'bar3' is not facet-valid with respect to enumeration '[bar, bar2]'. It must be a value from the enumeration.
[Error] sample-bad-values.xml:3:34:cvc-complex-type.2.2: Element 'Config' must have no element [children], and the value must be valid.
[Error] sample-bad-values.xml:4:34:cvc-enumeration-valid: Value 'boox' is not facet-valid with respect to enumeration '[boom, box]'. It must be a value from the enumeration.
[Error] sample-bad-values.xml:4:34:cvc-complex-type.2.2: Element 'Config' must have no element [children], and the value must be valid.

使用 Online Schema Validator service (linked from Xerces Using XML Schemas) 运行“Apache Xerces-J (v 2.12.2) XML 模式验证器进行测试”。