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 < 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 < 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) < 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 < 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 < 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 <= 300 and number > 200
else if (@dept = 'MEN')
then number < 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 < 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 < 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 < 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 < 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 < 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>
