基于属性值

时间:2016-01-01 09:44:17

标签: xml xsd xml-validation

是否可以在XML Schema中定义基于属性值的序列顺序/限制? 在XML中,有container个节点仅保留item个节点。第一个item节点始终为delimiter,其他item个节点必须仅包含属性值 category1 category2 < /强>

例如,有效文件是:

<root>
  <container>
    <item attr="delimiter">some_value</item>
    <item attr="category1">test1</item>
    <item attr="category1">test2</item>
    ....
  </container>

  <container>
    <item attr="delimiter">some_value</item>
    <item attr="category2">test3</item>
    ...
  </container>
<root>

container 节点中,我们只能使用 item category1 <category2个节点/强>

错误的XML示例:

<root>
  <container>
    <item attr="delimiter">some_value</item>
    <item attr="category1">test1</item>
    <item attr="category2">test2</item>
  </container>

  <container>
    <item attr="delimiter">some_value</item>
    <item attr="category2">test3</item>
    <item attr="category1">test1</item>
  </container>
<root>

XSD可以吗?

1 个答案:

答案 0 :(得分:3)

要直接回答您的问题,是的,这在XSD中是可行的,但是:

  1. 它需要XSD 1.1(参见下面的 XSD 1.1 for Original XML );它无法在XSD 1.0中完成:
  2. 这是糟糕的XML设计。更好的是如下,可以很容易地在XSD 1.0中表示:

    <root>
      <container>
        <delimiter>some_value</delimiter>
        <category1>test1</category1>
        <category1>test2</category1>
        ....
      </container>
    
      <container>
        <delimiter>some_value</delimiter>
        <category2>test3</category2>
        ...
      </container>
    </root>
    
  3. XSD 1.1 for Requested,Original XML

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
      xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
      <xs:element name="root">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="container" maxOccurs="unbounded">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="item" maxOccurs="unbounded">
                    <xs:complexType>
                      <xs:simpleContent>
                        <xs:extension base="xs:string">
                          <xs:attribute name="attr" use="required">
                            <xs:simpleType>
                              <xs:restriction base="xs:string">
                                <xs:enumeration value="delimiter"/>
                                <xs:enumeration value="category1"/>
                                <xs:enumeration value="category2"/>
                              </xs:restriction>
                            </xs:simpleType>
                          </xs:attribute>
                        </xs:extension>
                      </xs:simpleContent>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
                <xs:assert test="item[1]/@attr = 'delimiter' and
                  ((every $i in item[position() > 1] satisfies $i/@attr = 'category1') or
                   (every $i in item[position() > 1] satisfies $i/@attr = 'category2'))  "/>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>