我有一份需要订购的号码清单。目前它们在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>
答案 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可以通过断言来表达这样的约束。
<?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。