It's worth mentioning a few other complications that the implementation has to deal with, without going into gory detail:
Gregorian types. XSD 1.1 introduces a new facet which allows you to specify that the timezone on a date/time value
is mandatory or optional. It turns out to be easy to check this using XPath expressions for an xs:date
,
xs:time
, or xs:dateTime
; but there's no easy way to do it for xs:gYear
,
xs:gYearMonth
, and friends. Similarly, XSD 1.1 allows facets to control the range of these values,
for which XPath offers no support. The validator therefore includes a library of functions for handling the
Gregorian types.
Regular Expressions. The syntax for regular expressions contained in the XSD pattern facet is very similar
to the syntax for the XPath fn:matches()
function -- but not quite the same. Most of the differences are
extensions in the XPath version (for example, support for back-references), and since the schema compilers has done
static validation on the expression, we can ignore these differences. The remaining difficulty is the characters "^"
and "$", which represent themselves in XSD, but are meta-characters in XPath. To handle this we need to pre-process
the regular expression to replace occurrences of "^" and "$"(if not within square brackets) by "\^" and "\$".
Equality semantics. The equality matching rules in XSD 1.1, used for example by the enumeration facet or in
key/keyref comparison, don't correspond directly to any of the ways of testing equality in XPath. For example, in XPath
the integer 3 and the double 3e0 are equal, in XSD they are not. This also makes it difficult to use XPath maps to
enforce uniqueness constraints. It is therefore necessary to use a custom function for comparing atomic values, and
a function schemaComparable(x)
with the property that schemaComparable(x) eq schemaComparable(y)
under the XPath rules if and only if x
and y
are equal under the XSD rules.