Saxonica.com

Assertions on Simple Types

Saxon allows assertions on simple types to be defined. The mechanism is to define an xs:assert element as a child of the xs:restriction child of the xs:simpleType element (that is, it acts as an additional facet). The type must be an atomic type. The value of the test attribute of xs:assert is an XPath expression. .

The expression is evaluated with the value being validated as the context item. This will be an instance of the base type: for example, if you are restricting from xs:string, it will be a string; if you are restricting from xs:date, it will be an xs:date.

If the effective boolean value of the expression is true, the value is valid. If the effective boolean value is false, or if a dynamic error occurs while evaluating the expression, the value is invalid. Currently no diagnostics are produced to indicate why the value is deemed invalid, other than a statement that the xs:assert facet is violated.

The XPath expression has no access to any part of the document being validated, other than the atomic value of the actual element or attribute node. So the validation cannot be context-sensitive.

The XPath expression may make calls on Java extension functions in the normal way: see Writing extension functions (Java). This facility has not been tested on .NET but there is no intrinsic reason why it should not work. Allowing call-out to procedural programming languages means that you can perform arbitrary procedural validation of element and attribute values. Take care to disable use of extension functions if validating against a schema that is untrusted.

The following example validates that a date is in the past:


  <xs:element name="date">
    <xs:simpleType>
       <xs:restriction base="xs:date">
         <xs:assert test=". lt current-date()"/>
       </xs:restriction>   
    </xs:simpleType>
  </xs:element>

The following example validates that a string is a legal XPath expression. This relies on the fact that a failure evaluating the assertion is treated as "false":


  <xs:element name="xpath">
    <xs:simpleType>
       <xs:restriction base="xs:string">
         <xs:assert test="exists(saxon:expression(.))" xmlns:saxon="http://saxon.sf.net/"/>
       </xs:restriction>   
    </xs:simpleType>
  </xs:element>

Note how the in-scope namespaces for the XPath expression are taken from the in-scope namespaces of the containing xs:assert element.

Next