如何在XSD中指定有序列表

时间:2015-05-21 20:24:49

标签: 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>

是否有更好的方法可以在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>

1 个答案:

答案 0 :(得分: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>

可以为此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是否可以在元素上强制执行 排序 顺序

<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