XSLT 2.0 implementation
The context item, position, and size are now unset on entry to a stylesheet function. This means that
if the function depends on the context item (or the document containing the context item),
then an explicit parameter must be defined. For example, if the function defines <xsl:result select="count(//*)"/>
,
this must be changed to <xsl:result select="count($x//*)"/>
, with $x
being
supplied as a parameter in the function call. If the function attempts to reference the context item,
position, or size, a dynamic error is reported.
This change gives optimization benefits in all cases where functions are NOT dependent on the context.
The value
attribute of <xsl:number>
is now handled as described in the
XSLT 2.0 specification: the value may be a sequence, and the items in the sequence are converted to integers
using the casting rules. A recoverable error occurs if casting to an integer is not possible, or
if the value is not positive. {numb07, numb20}
A side-effect of this change is that a user-written Numberer
must be changed to handle a long
argument rather than an int
as previously.
The code for assignment of variables and parameters has been changed to use the argument conversion
rules defined in XPath (without backwards compatibility mode). This is a weaker conversion than previously:
essentially, the select
expression must deliver a value of the correct type, it will not be converted
to the required type except in the case where the supplied value is an untyped node. This means, for example,
that if the required type is xs:integer
, you can supply an attribute node, but you cannot supply
a string or a double.
If a cast to the required type is wanted, it must now be written explicitly in the select expression. The error
will be reported statically if the expression could never yield a value of the right type, and will be reported
dynamically otherwise.
In a pattern starting key('k', $x)/...
, the variable $x
can now be multi-valued;
the pattern matches if it matches any of the values. {idky30}
The XSLT 1.0 rule that xsl:text
elements may not contain child elements has been
reinstated. This change anticipates changes to the XSLT 2.0 specification.
In limited circumstances, stylesheet functions (xsl:function
) now optimise tail-recursion.
The circumstances are that the select
expression of the xsl:result
instruction
must contain a call on the same function in the then
or else
part of a
conditional expression (which may be nested in further conditional expressions). It may require a little
care to write functions to exploit this.
The attribute override=yes|no
on xsl:function
is implemented.
This determines whether a user-written
stylesheet function should override a vendor-supplied or user-written Java function. The default is "yes".
{func19, func21}
This involved taking the function binding logic out of the ExpressionParser and putting it all in the static context. A simpler version of the routine is provided for StandaloneContext. The code has been structured so it can also test for arity (or even static type of arguments) as part of the binding algorithm, but this is not yet exploited.
A side-effect of this change is that it is now possible to call Saxon and EXSLT extension functions
when using free-standing XPath expressions, that is, expressions executed using the XPath API from Java,
or using saxon:evaluate(). It is also possible to call user-supplied Java extension functions
provided the URI maps implicitly to a Java class name (i.e., not relying on saxon:script
).
{saxon36, 37}
Sorting using xsl:sort
: I have changed the way data types are specified (in anticipation
of changes to the W3C specification). The data-type
attribute may now take
values text
or number
only.
The values text
and number
convert the actual sort
key to xs:string
or xs:double
respectively before doing the comparison.
If the data-type
attribute is omitted there
is no conversion. Values are then compared as supplied; if they are not comparable, a run-time error occurs.
If you want to force conversion to a type such as xs:dateTime
, use a casting function within
the select
expression, for example <xsl:sort select="xs:date(@birth-date)"/>
.
There is a small risk of backwards incompatibility if your stylesheet computes a numeric sort key and doesn't specify
a data-type: previously it would have been sorted as a string, it will now be sorted as a number.
I added a check (really a bug fix for 7.3) that when an element is annotated with a simple type
such as xs:integer
, the element is not allowed to have attributes. The type annotation for an element
with attributes must always be a complex type.