Datypic Logo

Definitive XML Schema

Priscilla Walmsley (pwalmsley@datypic.com)
2nd edition (September 2012)
Prentice Hall PTR; ISBN: 0132886723

Chapter 14: Assertions

Book Examples

Example 14-1. Assertions on simple and complex types

<xs:simpleType name="SizeType">
  <xs:restriction base="xs:integer">
    <xs:assertion test="$value != 0"/>
  </xs:restriction>
</xs:simpleType>
<xs:complexType name="ProductType">
  <xs:sequence>
    <xs:element name="number" type="xs:integer"/>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="size" type="SizeType"/>
  </xs:sequence>
  <xs:attribute name="dept" type="xs:string"/>
  <xs:assert test="(@dept = 'ACC' and number > 500) or
                   (number &lt; 300)"/>
</xs:complexType>

Example 14-2. An assertion on a simple type

<xs:simpleType name="SizeType">
  <xs:restriction base="xs:integer">
    <xs:assertion test="$value != 0"/>
  </xs:restriction>
</xs:simpleType>

Example 14-3. An assertion on the simple content of a complex type

<xs:complexType name="SizeType">
  <xs:simpleContent>
    <xs:extension base="xs:integer">
      <xs:attribute name="system" type="xs:string"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>
<xs:complexType name="RestrictedSizeType">
  <xs:simpleContent>
    <xs:restriction base="SizeType">
      <xs:assertion test="$value != 0"/>
    </xs:restriction>
  </xs:simpleContent>
</xs:complexType>

Example 14-4. A simple type with more than one assertion

<xs:simpleType name="DepartmentCodeType">
  <xs:restriction base="xs:token">
    <xs:assertion test="not(contains($value,'X'))"/>
    <xs:assertion test="substring($value,2,2) != '00'"/>
    <xs:length value="3"/>
  </xs:restriction>
</xs:simpleType>

Example 14-5. Using parentheses to change evaluation order

<xs:simpleType name="SizeType">
  <xs:restriction base="xs:integer">
    <xs:assertion test="($value &lt; 12 or $value > 50)
                        and $value != 0"/>
  </xs:restriction>
</xs:simpleType>

Example 14-6. Using parentheses to create sequences

<xs:simpleType name="DepartmentCodeType">
  <xs:restriction base="xs:token">
    <xs:assertion test="$value = ('ACC','WMN','MEN')"/>
  </xs:restriction>
</xs:simpleType>

Example 14-7. Assertions with type errors

<xs:simpleType name="SizeType">
  <xs:restriction base="xs:integer">
    <xs:assertion test="string-length($value) &lt; 2"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="DepartmentCodeType">
  <xs:restriction base="xs:string">
    <xs:assertion test="$value != 001"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="EffectiveDateTimeType">
  <xs:restriction base="xs:dateTime">
    <xs:assertion test="$value > '2000-01-01T12:00:00'"/>
  </xs:restriction>
</xs:simpleType>

Example 14-8. Assertions with corrected type errors

<xs:simpleType name="SizeType">
  <xs:restriction base="xs:integer">
    <xs:maxExclusive value="100"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="DepartmentCodeType">
  <xs:restriction base="xs:string">
    <xs:assertion test="$value != '001'"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="EffectiveDateTimeType">
  <xs:restriction base="xs:dateTime">
    <xs:assertion test="$value >
                        xs:dateTime('2000-01-01T12:00:00')"/>
  </xs:restriction>
</xs:simpleType>

Example 14-9. A simple type with inherited assertions

<xs:simpleType name="DepartmentCodeType">
  <xs:restriction base="xs:token">
    <xs:assertion test="not(contains($value,'X'))"/>
    <xs:length value="3"/>
  </xs:restriction>
</xs:simpleType>
<xs:simpleType name="NonOverheadDepartmentCodeType">
  <xs:restriction base="DepartmentCodeType">
    <xs:assertion test="substring($value,2,2) != '00'"/>
  </xs:restriction>
</xs:simpleType>

Example 14-10. An assertion on a list type

<xs:simpleType name="SizeListType">
  <xs:restriction>
    <xs:simpleType>
      <xs:list itemType="xs:integer"/>
    </xs:simpleType>
    <xs:assertion test="$value[1] = 0"/>
  </xs:restriction>
</xs:simpleType>

Example 14-11. Assertions on a list type and its item type

<xs:simpleType name="SizeListType">
  <xs:restriction>
    <xs:simpleType>
      <xs:list>
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:assertion test="$value &lt; 12"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:list>
    </xs:simpleType>
    <xs:assertion test="count($value) > 2"/>
  </xs:restriction>
</xs:simpleType>

Example 14-12. An assertion on a complex type

<xs:element name="product" type="ProductType"/>
<xs:complexType name="ProductType">
  <xs:sequence>
    <xs:element name="number" type="xs:integer"/>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="size" type="xs:integer"/>
  </xs:sequence>
  <xs:attribute name="dept" type="xs:string"/>
  <xs:assert test="(@dept = 'ACC' and number > 500) or
                   (number &lt; 300)"/>
</xs:complexType>

Example 14-13. An assertion with a multistep path

<xs:element name="catalog" type="CatalogType"/>
<xs:complexType name="CatalogType">
  <xs:sequence>
    <xs:element name="product" type="ProductType"
                maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute name="maxNumber" type="xs:integer"/>
  <xs:assert test="not(max(product/number) > @maxNumber)"/>
</xs:complexType>
<xs:complexType name="ProductType">
  <xs:sequence>
    <xs:element name="number" type="xs:integer"/>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="size" type="xs:integer"/>
  </xs:sequence>
  <xs:attribute name="dept" type="xs:string"/>
</xs:complexType>

Example 14-14. An assertion using conditional expressions

<xs:complexType name="ProductType">
  <xs:sequence>
    <xs:element name="number" type="xs:integer"/>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="size" type="xs:integer"/>
  </xs:sequence>
  <xs:attribute name="dept" type="xs:string"/>
  <xs:assert test="if (@dept = 'ACC')
                   then number > 500
                   else if (@dept = 'WMN')
                   then number &lt;= 300 and number > 200
                   else if (@dept = 'MEN')
                   then number &lt; 200
                   else false()"/>
</xs:complexType>

Example 14-15. Assertions in complex type extension

<xs:complexType name="ProductType">
  <xs:sequence>
    <xs:element name="number" type="xs:integer"/>
    <xs:element name="name" type="xs:string"/>
  </xs:sequence>
  <xs:attribute name="dept" type="xs:string"/>
  <xs:assert test="(@dept = 'ACC' and number > 500) or
                   (number &lt; 300)"/>
</xs:complexType>

Example 14-16. Assertions in complex type restriction

<xs:complexType name="ProductType">
  <xs:sequence>
    <xs:element name="number" type="xs:integer"/>
    <xs:element name="name" type="xs:string" minOccurs="0"/>
    <xs:element name="size" type="xs:integer" minOccurs="0"/>
  </xs:sequence>
  <xs:attribute name="dept" type="xs:string"/>
  <xs:assert test="(@dept = 'ACC' and number > 500) or
                   (number &lt; 300)"/>
</xs:complexType>
<xs:complexType name="RestrictedProductType">
  <xs:complexContent>
    <xs:restriction base="ProductType">
      <xs:sequence>
        <xs:element name="number" type="xs:integer"/>
        <xs:element name="name" type="xs:string"/>
        <xs:element name="size" type="xs:integer" minOccurs="0"/>
      </xs:sequence>

Example 14-17. An assertion on a complex type with simple content

<xs:complexType name="SizeType">
  <xs:simpleContent>
    <xs:extension base="xs:integer">
      <xs:attribute name="system" type="xs:string"/>
      <xs:assert test="if (@system='US')
                       then $value &lt; 20
                       else $value >= 20"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>

Example 14-18. Assertions using prefixed element names

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://datypic.com/prod"
           xmlns:prod="http://datypic.com/prod"
           elementFormDefault="qualified">
  <xs:element name="product" type="ProductType"/>
  <xs:complexType name="ProductType">
    <xs:sequence>
      <xs:element name="number" type="xs:integer"/>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="size" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="dept" type="xs:string"/>
    <xs:assert test="(@dept = 'ACC' and prod:number > 500) or
                     (prod:number &lt; 300)"/>
    <xs:assert test="if (@dept = 'ACC')
                     then not(prod:size)
                     else true()"/>
  </xs:complexType>
</xs:schema>

Example 14-19. Assertions using xpathDefaultNamespace

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://datypic.com/prod"
           xmlns:prod="http://datypic.com/prod"
           elementFormDefault="qualified"
           xpathDefaultNamespace="http://datypic.com/prod">
  <xs:element name="product" type="prod:ProductType"/>
  <xs:complexType name="ProductType">
    <xs:sequence>
      <xs:element name="number" type="xs:integer"/>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="size" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="dept" type="xs:string"/>
    <xs:assert test="(@dept = 'ACC' and number > 500) or
                     (number &lt; 300)"/>
    <xs:assert test="if (@dept = 'ACC')
                     then not(size)
                     else true()"/>
  </xs:complexType>
</xs:schema>

Example 14-20. Conditional type assignment with default type

<xs:element name="product">
  <xs:alternative test="@dept='ACC'" type="AccessoryType"/>
  <xs:alternative test="@dept='WMN' or @dept='MEN'"
                  type="ClothingType"/>
  <xs:alternative type="ProductType"/>
</xs:element>

Example 14-21. Conditional type assignment with declared type

<xs:element name="product" type="ProductType">
  <xs:alternative test="@dept='ACC'" type="AccessoryType"/>
  <xs:alternative test="@dept='WMN' or @dept='MEN'"
                  type="ClothingType"/>
</xs:element>

Example 14-22. Conditional type assignment with no default

<xs:element name="product">
  <xs:alternative test="@dept='ACC'" type="AccessoryType"/>
  <xs:alternative test="@dept='WMN' or @dept='MEN'"
                  type="ClothingType"/>
</xs:element>

Example 14-23. Using the error type as the default

<xs:element name="product">
  <xs:alternative test="@dept='ACC'" type="AccessoryType"/>
  <xs:alternative test="@dept='WMN' or @dept='MEN'"
                  type="ClothingType"/>
  <xs:alternative type="xs:error"/>
</xs:element>

Example 14-24. Using the error type with a test

<xs:element name="product">
  <xs:alternative test="not(@dept)" type="xs:error"/>
  <xs:alternative test="@dept='ACC'" type="AccessoryType"/>
  <xs:alternative test="@dept='WMN' or @dept='MEN'"
                  type="ClothingType"/>
</xs:element>

Example 14-25. Conditional type assignment with globally declared attribute

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://datypic.com/prod"
           xmlns:prod="http://datypic.com/prod"
           elementFormDefault="qualified">
  <xs:element name="product" type="prod:ProductType">
    <xs:alternative test="@prod:dept='ACC'"
                    type="prod:AccessoryType"/>
    <xs:alternative test="@prod:dept='WMN' or @prod:dept='MEN'"
                    type="prod:ClothingType"/>
  </xs:element>
  <xs:complexType name="ProductType">
    <xs:sequence>
      <xs:element name="number" type="xs:integer"/>
      <xs:element name="name" type="xs:string"/>
    </xs:sequence>
    <xs:attribute ref="prod:dept"/>
  </xs:complexType>
  <xs:attribute name="dept" type="xs:string"/>
  <!--...-->
</xs:schema>

Example 14-26. Instance with an inherited attribute

<workTitles language="en">
  <title>Time Transfixed</title>
  <title language="fr">La Durée poignardée</title>
</workTitles>

Example 14-27. Assertions on inherited attribute

<xs:element name="workTitles" type="WorkTitlesType"/>
<xs:complexType name="WorkTitlesType">
  <xs:sequence>
    <xs:element name="title" maxOccurs="unbounded"
                type="TitleType">
      <xs:alternative test="@language='en'"
                      type="EnglishTitleType"/>
    </xs:element>
  </xs:sequence>
  <xs:attribute name="language" type="xs:language"
                inheritable="true"/>
</xs:complexType>
<xs:complexType name="EnglishTitleType">
  <xs:simpleContent>
    <xs:restriction base="TitleType">
      <xs:pattern value="\p{IsBasicLatin}+"/>
    </xs:restriction>
  </xs:simpleContent>
</xs:complexType>
<xs:complexType name="TitleType">
  <xs:simpleContent>
    <xs:extension base="xs:string">
      <xs:attribute name="language" type="xs:language"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>