构建需要元素或属性的XML架构,但不能同时构建两者

时间:2013-05-21 14:08:03

标签: xml xsd

我想创建一个具有以下约束的XML模式:

  • 根元素应为list
  • list包含一组node元素。
  • node元素可以具有value属性。
  • node元素可以包含value元素。
  • node元素只能包含(和完全)一个value属性或value元素。

以下是验证上述约束的有效XML示例:

<?xml version="1.0" ?>
<list>
    <node id="1" value="A" />
    <node id="2">
        <value>B</value>
    </node>
</list>

我尝试了以下XSD架构:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="list">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="node" maxOccurs="unbounded" minOccurs="0">
          <xs:complexType mixed="true">
            <xs:sequence>
              <xs:element type="xs:string" name="value" minOccurs="0"/>
            </xs:sequence>
            <xs:attribute type="xs:byte" name="id" use="optional"/>
            <xs:attribute type="xs:string" name="value" use="optional"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

此XSD架构验证我的第一个和第二个约束,但不验证第三个约束。

以下XML示例根据我的约束无效,但是它对我之前的XSD架构有效。

<?xml version="1.0" ?>
<list>
    <node id="2" value="A" /> <!-- valid -->
    <node id="4">
        <value>D</value>
    </node><!-- valid -->
    <node id="1" /><!-- not valid, missing value -->
    <node id="3" value="B">
        <value>C</value>
    </node><!-- not valid, both attribute and element are declared -->
</list>

如何更改架构以验证所有约束?

提前致谢。

2 个答案:

答案 0 :(得分:4)

使用XSD 1.0无法做到这一点。

XSD 1.1应该可以使用断言:

<xs:assert test="not(@value and value)"/>

如果@valuevalue都存在则失败。要检查是否只有一个属性或子元素使用:

<xs:assert test="count((value, @value))=1"/>
正如Michael Kay在评论中所建议的那样。

可能可以使用Schematron等其他一些XML验证技术。

答案 1 :(得分:0)

您可以使用required元素创建第一个类型,使用required元素创建第二个类型。然后使用包含两种类型的choice compositor。