如何在XSD中指定有序列表

ste*_*225 1 xml 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>
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来做到这一点,它可以在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>
Run Code Online (Sandbox Code Playgroud)

kjh*_*hes 6

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>
Run Code Online (Sandbox Code Playgroud)

可以为此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>
Run Code Online (Sandbox Code Playgroud)

但是改进很明显:消除组件名称中的索引编号:

<values>
  <value>0.2</value>
  <value>0.4</value>
  <value>0.6</value>
  <!-- ... -->
  <value>1.8</value>
</values>
Run Code Online (Sandbox Code Playgroud)

这种改进的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>
Run Code Online (Sandbox Code Playgroud)

现在有人可能会问XSD是否可以对这些元素强制执行排序顺序

<values>
  <value>0.2</value>
  <value>0.4</value>
  <value>0.6</value>
</values>
Run Code Online (Sandbox Code Playgroud)

会有效,但是

<values>
  <value>0.6</value>
  <value>0.2</value>
  <value>0.4</value>
</values>
Run Code Online (Sandbox Code Playgroud)

会无效的.

这在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>
Run Code Online (Sandbox Code Playgroud)

信用:断言测试的想法是基于Michael Kay的想法.