Wednesday, February 28, 2018

XML Schema 1.1 enhancements for simpleType with variety list

In this blog post, I wish to express my thoughts about new features that have been introduced in XML Schema 1.1 while defining XSD simpleType lists. I'd like to write few XML Schema validation examples here illustrating the same.

Example 1: Using the <xs:assertion> facet, to enforce sorted order on the list data.

Here's the XSD 1.1 document:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" vc:minVersion="1.1"
                    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">

   <xs:element name="X">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="a" type="xs:integer"/>
            <xs:element name="b">
               <xs:simpleType>
                  <xs:restriction base="IntegerList">                   
                     <xs:assertion test="every $val in (for $x in 1 to count($value)-1 return ($value[$x] le $value[$x+1])) 
                                         satisfies ($val eq true())">
                        <xs:annotation>
                           <xs:documentation>
                              Assertion facet checking that, items in the list are in ascending sorted order.
                           </xs:documentation>
                        </xs:annotation>
                     </xs:assertion>
                   </xs:restriction>               
               </xs:simpleType>
            </xs:element>
         </xs:sequence>
      </xs:complexType>
   </xs:element>

   <xs:simpleType name="IntegerList">
      <xs:list itemType="xs:integer"/>
   </xs:simpleType>

</xs:schema>

A valid XML document, when validated by the above schema document:

<?xml version="1.0"?>
<X>
   <a>100</a>
   <b>-20 1 2 3</b>
</X>

(the integer list in element "b", is sorted)

An invalid XML document, when validated by the above schema document:

<?xml version="1.0"?>
<X>
   <a>100</a>
   <b>-20 1 2 3 1</b>
</X>

(the integer list in element "b", is not in a sorted order)

Example 2: Using the <xs:assertion> facet, to enforce size of the list using relational operators other than equality (the equality was supported by XSD 1.0 using the xs:length facet).

Here's the XSD 1.1 document:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" vc:minVersion="1.1"
                    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">

   <xs:element name="X">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="a" type="xs:integer"/>
            <xs:element name="b">
               <xs:simpleType>
                  <xs:restriction base="IntegerList">                   
                     <xs:assertion test="count($value) lt 10">
                        <xs:annotation>
                           <xs:documentation>
                              Assertion facet checking that, cardinality/size of list should be less than 10.
                           </xs:documentation>
                        </xs:annotation>
                     </xs:assertion>
                   </xs:restriction>               
               </xs:simpleType>
            </xs:element>
         </xs:sequence>
      </xs:complexType>
   </xs:element>

   <xs:simpleType name="IntegerList">
      <xs:list itemType="xs:integer"/>
   </xs:simpleType>

</xs:schema>

A valid XML document, when validated by the above schema document:

<?xml version="1.0"?>
<X>
   <a>100</a>
   <b>-20 1 2 3</b>
</X>

(the integer list in element "b", has less than 10 items)

An invalid XML document, when validated by the above schema document:

<?xml version="1.0"?>
<X>
   <a>100</a>
   <b>-20 1 2 3 1 1 1 1 1 1 1</b>
</X>

(the integer list in element "b", has more than 10 items)

Example 3: Using the <xs:assertion> facet, to enforce that each item of list must be an even number.

Here's the XSD 1.1 document:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" vc:minVersion="1.1"
                    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">

   <xs:element name="X">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="a" type="xs:integer"/>
            <xs:element name="b">
               <xs:simpleType>              
          <xs:list>
             <xs:annotation>
                <xs:documentation>
                   The simpleType definition below, is itemType of this list.
                </xs:documentation>
             </xs:annotation>
             <xs:simpleType>
                <xs:annotation>
                  <xs:documentation>
                      Every item of list must be an even number.
                  </xs:documentation>
                </xs:annotation>
                <xs:restriction base="xs:integer">
                   <xs:assertion test="$value mod 2 = 0"/>
                </xs:restriction>
             </xs:simpleType>
          </xs:list>
               </xs:simpleType>
            </xs:element>
         </xs:sequence>
      </xs:complexType>
   </xs:element>

</xs:schema>

A valid XML document, when validated by the above schema document:

<?xml version="1.0"?>
<X>
   <a>100</a>
   <b>2 4 6</b>
</X>

(the integer list in element "b", has each item as even number)

An invalid XML document, when validated by the above schema document:

<?xml version="1.0"?>
<X>
   <a>100</a>
   <b>2 1 6</b>
</X>

(the integer list in element "b", has one or more item not even)

As illustrated by the above examples, some new XML Schema validation scenarios are possible with the introduction of <xs:assertion> facet on XSD simple types in 1.1 version of the XML Schema language.

2018-04-11: I've been thinking about this post for a while, and wish to say something about sorting. I think, sorting as a problem in programming is more meaningful to solve, when we have to *do* sorting and not when, we have to determine whether some list is sorted or not. What my XSD Example 1 showed above, is *not doing* sorting but the other thing. Nevertheless, I'm happy to discover what my XSD shows.