如何在 XSD 中指定有序列表

How to specify an ordered list in XSD

我有一个需要订购的号码列表。目前他们在 XML 中:

<value_1>0.2</value_1>
<value_2>0.4</value_2>
<value_3>0.6</value_3>
...
<value_N>1.8</value_N>

是否有更好的方法可以在 XSD 中很好地定义它并以指定的顺序从解析器返回数据?

编辑 XSD 的片段:

<xs:complexType>
    <xs:sequence>
        <xs:element name="value_1" type="xs:decimal"/>
        <xs:element name="value_2" type="xs:decimal"/>
        <xs:element name="value_3" type="xs:decimal"/>
        ...
        <xs:element name="value_N" type="xs:decimal"/>
    </xs:sequence>
</xs:complexType>

XML 中的元素按照其在文档中的顺序固有地排序。此顺序很重要(与属性的顺序不同)并将由解析器保留。

XML 文档必须有一个根元素,所以让我们将您的示例元素包装在一个包含元素中:

<values>
  <value_1>0.2</value_1>
  <value_2>0.4</value_2>
  <value_3>0.6</value_3>
  <!-- ... -->
  <value_N>1.8</value_N>
</values>

这个XML可以写一个XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="values">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="value_1" type="xs:decimal"/>
        <xs:element name="value_2" type="xs:decimal"/>
        <xs:element name="value_3" type="xs:decimal"/>
        <!-- ... -->
        <xs:element name="value_N" type="xs:decimal"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

但改进是显而易见的:从组件名称中删除索引号:

<values>
  <value>0.2</value>
  <value>0.4</value>
  <value>0.6</value>
  <!-- ... -->
  <value>1.8</value>
</values>

这个改进的 XML 的 XSD 同样被精简了(并且实际上也可以处理无限数量的 value 元素):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="values">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="value" type="xs:decimal" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

现在有人可能会问 XSD 是否可以对元素执行 sorted 顺序

<values>
  <value>0.2</value>
  <value>0.4</value>
  <value>0.6</value>
</values>

是有效的,但是

<values>
  <value>0.6</value>
  <value>0.2</value>
  <value>0.4</value>
</values>

将无效。

这在 XSD 1.0 中是不可能的,但是 XSD 1.1 可以通过断言表达这样的约束。

在 XSD 1.1

中断言排序顺序
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
  vc:minVersion="1.1">
  <xs:element name="values">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="value" type="xs:decimal" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:assert test="every $v in value 
                       satisfies not(number($v) lt 
                                     number($v/preceding-sibling::value[1]))"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

信用:断言测试的思路是基于one from Michael Kay.