How to specify an ordered list in XSD

前端 未结 1 1741
感情败类
感情败类 2021-01-24 20:36

I have a list of numbers that need to be ordered. Currently they are in the XML as such:

0.2
0.4
&l         


        
相关标签:
1条回答
  • 2021-01-24 21:05

    Elements in XML are inherently ordered per their order in the document. This order is significant (unlike that of attributes) and will be preserved by parsers.

    XML documents must have a single root element, so let's wrap your example elements in a single containing element:

    <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>
    

    An XSD can be written for this XML:

    <?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>
    

    But an improvement is immediately obvious: Eliminate the indexing number from the component name:

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

    The XSD for this improved XML is similarly streamlined (and also can actually handle an indefinite number of value elements as well):

    <?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>
    

    Now one might ask whether the XSD can enforce a sorted order on the elements such that

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

    would be valid, but

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

    would be invalid.

    This is not possible to do in XSD 1.0, however XSD 1.1 can express such a constraint via assertions.

    Asserting sorted ordering in 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>
    

    Credit: The idea for the assertion test is based on one from Michael Kay.

    0 讨论(0)
提交回复
热议问题