Conditional Type Assignment Xsd

On By In 1

XML Schema 1.1 : Conditional Type Assignment revisited

One of the other features of XML Schema 1.1, that I like very much is "conditional type assignment", or CTA. The only requirement is, that there must be an attribute on an XML element to use this feature.

Here is a very simple example.

I'm directly writing an XML Schema 1.1 document below using CTA:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

   <xs:element name="X">
        <xs:alternative type="Type1" test="@xa = 1"/>
        <xs:alternative type="Type2" test="@xa = 2"/>
        <xs:alternative type="xs:error"/>
   </xs:element>
  
   <xs:complexType name="Type1">
        <xs:sequence>
            <xs:element name="a" type="xs:int"/>
            <xs:element name="b" type="xs:int"/>
        </xs:sequence>
        <xs:attribute name="xa" type="xs:int"/>
   </xs:complexType>
  
   <xs:complexType name="Type2">
        <xs:sequence>
            <xs:element name="p" type="xs:int"/>
            <xs:element name="q" type="xs:int"/>
        </xs:sequence>
        <xs:attribute name="xa" type="xs:int"/>
   </xs:complexType>
 
</xs:schema>

The requirement of XML Schema 1.1 validation in this case is: If the attribute "xa" on element "X" has value 1, then element "X" has a certain type. If the value of attribute "xa" is 2, then element "X" has another type.

The two valid XML documents for the given XML Schema document are following:

<?xml version="1.0" encoding="UTF-8"?>
<X xa="1">
    <a>1</a>
    <b>2</b> 
</X>

and,

<?xml version="1.0" encoding="UTF-8"?>
<X xa="2">
  <p>1</p>
  <q>2</q> 
</X>

For anything else as value of attribute "xa", or infact any other kind of content the element "X" will be assigned the type xs:error (which makes the element "X" invalid").

Book examples

Example 14-1. Assertions on simple and complex types

<xs:simpleTypename="SizeType"><xs:restrictionbase="xs:integer"><xs:assertiontest="$value != 0"/></xs:restriction></xs:simpleType><xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="SizeType"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="(@dept = 'ACC' and number > 500) or (number &lt; 300)"/></xs:complexType>

Example 14-2. An assertion on a simple type

<xs:simpleTypename="SizeType"><xs:restrictionbase="xs:integer"><xs:assertiontest="$value != 0"/></xs:restriction></xs:simpleType>

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

<xs:complexTypename="SizeType"><xs:simpleContent><xs:extensionbase="xs:integer"><xs:attributename="system"type="xs:string"/></xs:extension></xs:simpleContent></xs:complexType><xs:complexTypename="RestrictedSizeType"><xs:simpleContent><xs:restrictionbase="SizeType"><xs:assertiontest="$value != 0"/></xs:restriction></xs:simpleContent></xs:complexType>

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

<xs:simpleTypename="DepartmentCodeType"><xs:restrictionbase="xs:token"><xs:assertiontest="not(contains($value,'X'))"/><xs:assertiontest="substring($value,2,2) != '00'"/><xs:lengthvalue="3"/></xs:restriction></xs:simpleType>

Example 14-5. Using parentheses to change evaluation order

<xs:simpleTypename="SizeType"><xs:restrictionbase="xs:integer"><xs:assertiontest="($value &lt; 12 or $value > 50) and $value != 0"/></xs:restriction></xs:simpleType>

Example 14-6. Using parentheses to create sequences

<xs:simpleTypename="DepartmentCodeType"><xs:restrictionbase="xs:token"><xs:assertiontest="$value = ('ACC','WMN','MEN')"/></xs:restriction></xs:simpleType>

Example 14-7. Assertions with type errors

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

Example 14-8. Assertions with corrected type errors

<xs:simpleTypename="SizeType"><xs:restrictionbase="xs:integer"><xs:maxExclusivevalue="100"/></xs:restriction></xs:simpleType><xs:simpleTypename="DepartmentCodeType"><xs:restrictionbase="xs:string"><xs:assertiontest="$value != '001'"/></xs:restriction></xs:simpleType><xs:simpleTypename="EffectiveDateTimeType"><xs:restrictionbase="xs:dateTime"><xs:assertiontest="$value > xs:dateTime('2000-01-01T12:00:00')"/></xs:restriction></xs:simpleType>

Example 14-9. A simple type with inherited assertions

<xs:simpleTypename="DepartmentCodeType"><xs:restrictionbase="xs:token"><xs:assertiontest="not(contains($value,'X'))"/><xs:lengthvalue="3"/></xs:restriction></xs:simpleType><xs:simpleTypename="NonOverheadDepartmentCodeType"><xs:restrictionbase="DepartmentCodeType"><xs:assertiontest="substring($value,2,2) != '00'"/></xs:restriction></xs:simpleType>

Example 14-10. An assertion on a list type

<xs:simpleTypename="SizeListType"><xs:restriction><xs:simpleType><xs:listitemType="xs:integer"/></xs:simpleType><xs:assertiontest="$value[1] = 0"/></xs:restriction></xs:simpleType>

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

<xs:simpleTypename="SizeListType"><xs:restriction><xs:simpleType><xs:list><xs:simpleType><xs:restrictionbase="xs:integer"><xs:assertiontest="$value &lt; 12"/></xs:restriction></xs:simpleType></xs:list></xs:simpleType><xs:assertiontest="count($value) > 2"/></xs:restriction></xs:simpleType>

Example 14-12. An assertion on a complex type

<xs:elementname="product"type="ProductType"/><xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="xs:integer"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="(@dept = 'ACC' and number > 500) or (number &lt; 300)"/></xs:complexType>

Example 14-13. An assertion with a multistep path

<xs:elementname="catalog"type="CatalogType"/><xs:complexTypename="CatalogType"><xs:sequence><xs:elementname="product"type="ProductType"maxOccurs="unbounded"/></xs:sequence><xs:attributename="maxNumber"type="xs:integer"/><xs:asserttest="not(max(product/number) > @maxNumber)"/></xs:complexType><xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="xs:integer"/></xs:sequence><xs:attributename="dept"type="xs:string"/></xs:complexType>

Example 14-14. An assertion using conditional expressions

<xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="xs:integer"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="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:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="(@dept = 'ACC' and number > 500) or (number &lt; 300)"/></xs:complexType><xs:complexTypename="ExtendedProductType"><xs:complexContent><xs:extensionbase="ProductType"><xs:sequence><xs:elementname="size"type="xs:integer"minOccurs="0"/></xs:sequence><xs:asserttest="if (@dept = 'ACC') then not(size) else true()"/></xs:extension></xs:complexContent></xs:complexType>

Example 14-16. Assertions in complex type restriction

<xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"minOccurs="0"/><xs:elementname="size"type="xs:integer"minOccurs="0"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="(@dept = 'ACC' and number > 500) or (number &lt; 300)"/></xs:complexType><xs:complexTypename="RestrictedProductType"><xs:complexContent><xs:restrictionbase="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="xs:integer"minOccurs="0"/></xs:sequence><xs:attributename="dept"type="xs:string"use="required"/><xs:asserttest="if (@dept = 'ACC') then not(size) else true()"/></xs:restriction></xs:complexContent></xs:complexType>

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

<xs:complexTypename="SizeType"><xs:simpleContent><xs:extensionbase="xs:integer"><xs:attributename="system"type="xs:string"/><xs:asserttest="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:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema"targetNamespace="http://datypic.com/prod"xmlns:prod="http://datypic.com/prod"elementFormDefault="qualified"><xs:elementname="product"type="ProductType"/><xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="xs:string"minOccurs="0"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="(@dept = 'ACC' and prod:number > 500) or (prod:number &lt; 300)"/><xs:asserttest="if (@dept = 'ACC') then not(prod:size) else true()"/></xs:complexType></xs:schema>

Example 14-19. Assertions using

<xs:schemaxmlns: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:elementname="product"type="prod:ProductType"/><xs:complexTypename="ProductType"><xs:sequence><xs:elementname="number"type="xs:integer"/><xs:elementname="name"type="xs:string"/><xs:elementname="size"type="xs:string"minOccurs="0"/></xs:sequence><xs:attributename="dept"type="xs:string"/><xs:asserttest="(@dept = 'ACC' and number > 500) or (number &lt; 300)"/><xs:asserttest="if (@dept = 'ACC') then not(size) else true()"/></xs:complexType></xs:schema>

Example 14-20. Conditional type assignment with default type

<xs:elementname="product"><xs:alternativetest="@dept='ACC'"type="AccessoryType"/><xs:alternativetest="@dept='WMN' or @dept='MEN'"type="ClothingType"/><xs:alternativetype="ProductType"/></xs:element>

Example 14-21. Conditional type assignment with declared type

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

Example 14-22. Conditional type assignment with no default

<xs:elementname="product"><xs:alternativetest="@dept='ACC'"type="AccessoryType"/><xs:alternativetest="@dept='WMN' or @dept='MEN'"type="ClothingType"/></xs:element>

Example 14-23. Using the type as the default

<xs:elementname="product"><xs:alternativetest="@dept='ACC'"type="AccessoryType"/><xs:alternativetest="@dept='WMN' or @dept='MEN'"type="ClothingType"/><xs:alternativetype="xs:error"/></xs:element>

Example 14-24. Using the type with a test

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

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

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

Example 14-26. Instance with an inherited attribute

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

Example 14-27. Assertions on inherited attribute

<xs:elementname="workTitles"type="WorkTitlesType"/><xs:complexTypename="WorkTitlesType"><xs:sequence><xs:elementname="title"maxOccurs="unbounded"type="TitleType"><xs:alternativetest="@language='en'"type="EnglishTitleType"/></xs:element></xs:sequence><xs:attributename="language"type="xs:language"inheritable="true"/></xs:complexType><xs:complexTypename="EnglishTitleType"><xs:simpleContent><xs:restrictionbase="TitleType"><xs:patternvalue="\p{IsBasicLatin}+"/></xs:restriction></xs:simpleContent></xs:complexType><xs:complexTypename="TitleType"><xs:simpleContent><xs:extensionbase="xs:string"><xs:attributename="language"type="xs:language"/></xs:extension></xs:simpleContent></xs:complexType>

0 comments

Leave a Reply

Your email address will not be published. Required fields are marked *