XPath 2.0 implementation

The type conversion rules as defined in the XPath 2.0 working draft are now implemented. This means that the rules for passing arguments to functions and operators are now stricter: you can't simply assume that the supplied value will be cast to the required type.

The rules are stricter if the stylesheet specifies version="2.0" than if it specifies version="1.0". The version attribute (or xsl:version on a literal result element) determines whether XPath 1.0 backwards compatibility mode is used for XPath expressions within its scope. With backwards compatibility mode on, certain conversions that were permitted in XPath 1.0 (for example, conversion of anything to a string or number, or extraction of the first item of a sequence) are still permitted under XPath 2.0. With this mode off, these conversions must be done explicitly in the function call. The only conversions that happen automatically under 2.0 are extraction of the value from a node: if the node is untyped (which with Saxon 7.4 will almost invariably be the case), the untyped value is then cast to the type required by the function signature. This means you can supply an untyped attribute as an operand to the "+" oeprator or the round() function, for example, but you cannot supply a string.

Division of two decimals (and also the mod operator) now produces a decimal. Previously it produced a double. The scale of the resulting decimal (the number of digits after the decimal point) is equal to the sum of the scales of the two decimals, plus 6. So, for example, 10.0 div 3 is 3.333333. There have been some other refinements to the xs:decimal implementation. Insignificant trailing zeros are always discarded. Conversion of a decimal to a string uses an integer representation if there is no fractional part, for example the result of 10.0 div 5.0 is diplayed as 2 (which doesn't match the current XPath specification).

Conversion of an empty sequence to a double now produces an empty sequence (not NaN as in XPath 1.0); conversion of any other non-numeric string to a double raises an error (rather than producing NaN). This follows the current XPath 2.0 specification.

I attempted to change the double-to-string conversion to fit the XPath 2.0 rules, but it hit numerous compatibility problems so I have held back on this. But positive and negative infinity are now represented as INF and -INF (previously they were Infinity and -Infinity). The strings INF and -INF are also recognized when casting a string to a double or float; XPath 1.0 had no way of constructing these values except by using a construct such as (1 div 0). {math95, math96}