This file describes changes for versions 7.0 and later. For changes prior to version 7.0, see http://saxon.sf.net/saxon6.5.2/changes.html.
This version of Saxon has been modified and tested to work with JDOM beta 0.8 and with FOP 0.20.3. In both cases, code changes were needed to work with these versions, and I have not tested whether the code still works with earlier versions; the chances are that it doesn't.
In general, bugs that have been cleared in Saxon 6.5.1 or Saxon 6.5.2 have also been cleared in this release. For details of the clearance of specific bugs, see the bug tracker at Sourceforge. Remember that closed bugs are not listed unless you ask for them.
href attribute of
xsl:result-document is now interpreted as a relative
URI, relative to the system ID of the principal result document. This works only where the system ID of the
principal output is known, and uses the "file://" protocol. The result document is no longer created
relative to the current working directory, for security reasons (it causes problems when executing
an untrusted stylesheet in a servlet environment).
Note that when Saxon is invoked from the command line, the -o option should be used to specify the
principal output destination. This will ensure that a suitable system ID is available. If the result document
is sent to the standard output stream (even if this is redirected to a file), Saxon will not know the
system identifier and will therefore be unable to create a secondary output destination using a relative
URI. It is still possible, of course, to specify an absolute URI as the value of the
attribute - note that this must be a URL, not a filename, so it will typically start with
It is now possible to specify an OutputURIResolver to be used to resolve the URI specified in the
attribute of the
xsl:result-document element. This will be used in place of the standard output URI
resolver. The OutputURIResolver is called when writing of the output document starts, at which point it must
return a JAXP Result object to act as the output destination. It is called again when writing of an output document
is complete. You can nominate an OutputURIResolver by calling
or by calling
If the -t option is used, a message is written to the standard error output identifying the
files written using using
It is now an error to use
xsl:result-document when the current output destination
is a temporary tree.
The meaning of the ALLOW_EXTENSION_FUNCTIONS attribute in the TransformerFactory has been
extended so that setting the value to
false also disables extension elements and
the creation of multiple output files. This is because all these operations carry similar risks
when a servlet is allowed to execute untrusted stylesheets.
Added support for the
separator attribute of
current() function may now be used in a pattern (specifically, within a predicate).
Its value is the node being tested against the pattern. For example,
matches any element that contains another element with the same name.
A global variable or parameter may now be used in the match pattern of
xsl:template, provided that it does
not cause a circularity (that is, it must be possible to evaluate the variable without calling
A global variable or parameter may now be used in the match pattern or the use expression
xsl:key, provided that it does
not cause a circularity (that is, it must be possible to evaluate the variable without using the
function against the key being defined)
key() function may now be used in the
match attributes of
xsl:key, provided the key definitions are not circular. (For example, key k1 can be defined
in terms of key k2, provided that k2 is not defined in terms of k1.)
group-ending-with attribute of
xsl:for-each-group is implemented. It is especially
useful where the last node in each group carries some kind of marker, for example
saxon:collation, to specify whether this collation
should be used as the default collation. If more than one collation is specified as the default, the last one wins.
If no default collation is specified, Unicode codepoint collation is used. The default collation is used by
the compare() function if no third argument is supplied, by xsl:sort if no collation is specified (for data type text
or string), and also by the comparison operators =, !=, <, >, etc.
The collation name is now a URI, not a QName.
Sorting and comparison according to Unicode codepoints can be achieved by setting up a collator as
<saxon:collation name="unicode" class="net.sf.saxon.sort.CodepointCollator"/>
The implementation of the "and" and "or" operators has reverted to two-valued logic, since three-valued logic didn't make it into the published XPath 2.0 working draft. (Actually, it seems 3-valued logic wasn't working in Saxon 7.0 anyway).
Changed the "==" and "!==" operators to "is" and "isnot".
Changed string literals to allow the delimiting quote marks to be doubled. For example,
<xsl:value-of select="'[He isn''t]'"/> displays the string
every expressions to allow multiple range variables,
some $i in //I, $j in //J satisfies $i = $j
Implemented the singleton value-comparison operators (eq, ne, gt, lt, ge, le). These return an error if applied to a sequence containing more than one item, and return the empty sequence if either operand is an empty sequence; when applied to singletons, they return the same result as the XPath 1.0 operators (=, !=, etc).
Less-than and greater-than comparisons between nodes and/or strings now do a lexicographic comparison using the default collating sequence; at XPath 1.0 they did a numeric comparison. A warning is output in this situation (and one or two other situations, but not all) to advise of the backwards incompatibility.
The rules for deciding when path expressions need to be sorted have been revised. As a result many cases now require no sort where previously a sort was done. Examples of such expressions include a/b/c, .//a, $x/a, //@a. In addition, most path expressions that return results in reverse document order are now sorted by a simple reversal, which is much faster than a full sort.
There's a temporary bug in that path expressions returning namespace nodes don't always return them in document order. I'm awaiting resolution of the XPath 2.0 data model rules before fixing this.
Suppress lazy evaluation of assignable variables. (This was designed to prevent a stack overflow, it didn't succeed, but it seems a good idea anyway).
Added the ability for a Source object to be supplied as the value of a stylesheet parameter or as the value returned by an extension function.
Added dateTime and date data types. Initially the only operations supported are the currentDateTime function, the dateTime and date constructors, and conversion between strings, dates, and dateTimes in both directions. Conversion to string uses the timezone of the current locale.
Implemented comparisons (equals, less-than, etc) between dates and dateTimes.
Also implemented sorting. The data-type of xsl:sort may take the two values "text" or "number"
(which are treated as synonyms of xs:string and xs:double) or any XML Schema built-in data type
for which sorting is supported. The values in the sequence to be sorted are converted to this
data type (using the same rules as for
cast as) and the rules for this data type
determine the sort order.
Note that (as required by the XML Schema specification) dateTime values are normalized to UTC. The original timezone specified when the dateTime was constructed is not retained. If no timezone is present, this fact is remembered. Such a dateTime is compared with other dateTimes as if it were a UTC dateTime.
Implemented the instance of operator (including the instance of only variant):
if ($x instance of xs:integer *) then x else y. The types that are currently
supported are the 19 primitive schema types (the namespace may be either of the two namespaces
permitted in XML Schema Part 2), the derived type xs:integer, the node types document, element,
attribute, text, comment, processing-instruction, or namespace, and the abstract types node, and item.
(There is no syntax currently for the general numeric type or for the general atomic type). The
type name may be followed by one of the qualifiers "*", "+", or "?" to indicate the number of
occurrences; if there is no qualifier, there must be exactly one occurrence. The more sophisticated
forms of type-checking, using schema-defined complex types, are not yet supported.
Implemented the cast as data-type expression, for example
cast as xs:boolean($x).
The conversion rules are the same as those which apply implicitly when a value is supplied
in a context where a different type is expected.
Implemented the treat as data-type expression. This doesn't actually have much use in an XSLT context, where type conversion is performed implicitly when required, and the semantics of the expression are probably not correctly implemented at this stage: the specification is still evolving.
A new API has been introduced for executing XPath expressions. This is simpler and safer than the API provided in previous releases, which was essentially improvised from implementation classes rather than being designed top-down as an interface suitable for application use. The API is loosely modelled on the proposed DOM Level 3 API for XPath.
The new API uses the class
net.sf.saxon.xpath.XPathEvaluator. This class provides a few
simple configuration interfaces to set the source document, the static context, and the context node,
plus a number of methods for evaluating XPath expressions. The static context can be omitted if the
expression does not use namespaces, external variables, or extension functions. If the expression uses
namespaces, an instance of StandaloneContext can be supplied, allowing the required namespaces to be
declared either explicitly, or by reference to the in-scope namespaces of some Node.
There are two methods for direct evaluation, evaluate() which returns a List containing the result of the expression (which in general is a sequence), and evaluateSingle() which returns the first item in the result (this is appropriate where it is known that the result will be single-valued). The results are returned as NodeInfo objects in the case of nodes, or as objects of the most appropriate Java class in the case of atomic values: for example, Boolean, Double, or String in the case of the traditional XPath 1.0 data types.
It is also possible to prepare an XPath expression for subsequent execution, using the createExpression() method on the XPathEvaluator class. This is worthwhile where the same expression is to be executed repeatedly. The compiled expression is represented by an instance of the class net.sf.saxon.xpath.XPathExpression, and it can be executed repeatedly, with different context nodes. However, the compiled expression is bound to one particular source document (this is to ensure that the same NamePool is used).
The design principle of this API is to minimize the number of Saxon classes that need to be used. Apart from the NodeInfo interface, which is needed when manipulating Saxon trees, only the four classes XPathProcessor, XPathExpression, StandaloneContext, and XPathException are needed. For convenience, XPathException and StandaloneContext have been moved to the net.sf.saxon.xpath package.
If you want to use extension functions or variables you will need to create your own implementation of StaticContext. Although this interface has been greatly simplified, this is still not to be attempted lightly.
The old APIs for executing expressions still exist for the time being, but they are likely to be less stable.
Changed ContentEmitter to check in startElement() that qname and local-name are both supplied; this checks against parser configuration errors. This change could (should?) be retrofitted to the 6.5 branch. The change also uses a stack of namecodes so that endElement() doesn't need to look up the names in the name pool. In implementing this change, I discovered that Saxon depends on the XML parser passing the QName argument to the startElement() call, something which according to the SAX2 specification is optional. However, all known parsers supply this argument, and the code changes to cope with its absence would damage performance, so I have simply documented this as a dependency on the parser.
Implemented infrastructure for data type support:
I have changed the implementation of temporary trees (result tree fragments). The FragmentValue class has disapeared. This delayed the construction of an actual tree until it the tree was actually used as a node-set: the effect was to optimize simple uses of temporary trees but at considerable cost to the more general usage which is now permitted in XSLT 2.0. Also, the introduction of tinytrees has reduced the value of this optimization. Therefore, a temporary tree is now constructed immediately as a real tree.
A side-effect of this change is that when disable-output-escaping is used while writing nodes to a tree, the instructions to switch escaping on and off are recorded in the tree in the form of the processing instructions defined by JAXP 1.1. Previously, these instructions were recorded in a form that kept the information through an xsl:copy-of instruction, but lost the information if the tree was processed in any other way. Note that the behavior of "sticky d-o-e" (that is, the effect of disabling output escaping when writing to a temporary tree) is currently an open issue in XSLT 2.0.
The indexes associated with keys are no longer referenced from each document instance, they are handled externally. This makes it easier to share the same index implementation across all the different document implementations. The indexes are now held by the KeyManager. It uses a WeakHashMap to ensure that when a document is removed from memory by the garbage collector, its indexes are removed too.
The mechanism for keeping stylesheet signatures in the namepool has been removed. It caused a creeping "memory leak" in continuously running services, and is not really needed. It was invented to allow namepools to be copied, but this facility has never been properly documented or tested. Instead, there is now a simple check that the source document and stylesheet are using the same namepool. (This change, or a simplified version of it, has also been made to 6.5.2).
The StaticContext interface has been greatly simplified, reducing duplication and making it easier to create a new implementation of this interface. This has been achieved partly by doing some work in the XPath ExpressionParser that was previously done in the StaticContext, and partly by changing those functions such as format-number() and sort() that only work in an XSLT context to check that the context is indeed XSLT before accessing the context information.
At the suggestion of Claudio Thomas [firstname.lastname@example.org], I have extended the sql:query instruction
to allow the attribute
disable-output-escaping="yes|no". This is useful where the database
content being retrieved contains XML or HTML markup that is to be preserved in the output. Use this
with care; it disables escaping for all the rows and columns retrieved, some of which may contain
special characters such as "<" and "&" that do need to be escaped.
This change has not been tested.
Added extension functions: saxon:parse() and saxon:serialize(). These allow conversion of a string containing well-formed XML to a tree structure, and vice-versa.
Added extension functions: saxon:string-to-unicode() and saxon:unicode-to-string(). These allow conversion between a string and a sequence of integers representing the Unicode values of the characters in the string.
Added extension functions saxon:pause-tracing() and saxon:resume-tracing().
The return value from an extension function may now be an implementation of
representing a sequence. The members of the
List must all implement
An argument to an extension function may now be the class
a subclass. If the supplied value is a sequence, the first node in the sequence is passed to the function;
it is an error if there is no node in the supplied sequence, or if the node is of the wrong type.
The rules for calling extension functions with a sequence-valued argument have been clarified, and
some new options are permitted, e.g. declaring the argument as
java.util.List. The possibilities
have not been extensively tested.
Implemented memo functions (thanks to Robert Brotherus for the suggestion).
If you specify the attribute
Saxon will keep a cache that maps the supplied argument values to the result of the
function, and if the function is called twice with the same arguments, the original
result will be returned without re-evaluating the function. Don't use this option on a function
that depends on the context, or on a function that creates a new temporary tree and
is required to create a new instance each time. Also note that there are cases where it
may be faster to re-evaluate the function than to do the lookup; this is especially true
if the argument is a large node-set.
This version introduces initial support of features defined in working drafts of XSLT 2.0 and XPath 2.0.
Version 7.0 should be regarded as an experimental alpha release. For production use, please continue to use Saxon 6.5
The Saxon package name has changed from com.icl.saxon to net.sf.saxon.
Any applications that use Saxon java classes directly (rather than relying on the JAXP
interface) will need to be modified. Note that this also affects the settings of the system
The entry point from the command line has changed from com.icl.saxon.StyleSheet to net.sf.saxon.Transform.
The namespace URI for saxon extensions has changed from http://icl.com/saxon to http://saxon.sf.net/. Note that many extensions have been withdrawn, as they are superseded by facilities in XPath 2.0 and/or XSLT 2.0.
To allow coexistence, the name of the JAR file for this release has changed to
saxon7.jar. The SQL extensions are now in a separate JAR file,
A transformation can now be executed directly from the JAR file using the command
java -jar saxon7.jar in place of
Saxon now requires JDK 1.2 or later to run. In consequence, Saxon will no longer work with the Microsoft Java VM, and the Instant Saxon version of the product is therefore no longer available.
Because Saxon no longer runs with the Java VM, it can now be run as an applet within Internet Explorer only if the Sun Java plug-in is installed. You can get this from http://java.sun.com/getjava. This may require some configuration changes because of the differences in security policy.
The following sections summarize the main new features. These assume familiarity with the XPath 2.0 and XSLT 2.0 specifications; however, summaries of the new syntax for expressions and XSLT elements are included in this package.
($a, $b, $c). Path expressions now return a sequence of nodes containing no duplicates, in document order.
1 to 10evaluates to the sequence
( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 )
*:localname(like prefix:*) is allowed in path expressions, and also in patterns and in
xsl:strip-spaceand xsl:preserve-space. It matches any node with the given local name, regardless of namespace.
xsl:value-ofelement has a new
separatorattribute, so it can be used to output a sequence.
xsl:for-eachelement supports arbitrary sequences.
xsl:for-each-groupinstruction, and the associated
current-group()function, are implemented.
xsl:resultelements are implemented; these replace
exslt:function. Note that the XSLT 2.0 specification is more restrictive as to what can appear in a function body: it has to be zero or more
xsl:paramelements, followed by zero or more
xsl:variableelements, followed by an
xsl:resultelement. However, this is not a serious restriction in practice, because most computations can now be carried out within a single XPath expression.
xsl:namespaceinstruction is implemented (it writes a namespace node to the result tree)
xsl:copy-ofcan now handle sequences containing simple-values (the simple value is converted to a string and written to the result tree). However, the
separatorattribute is not yet implemented.
xsl:documentelement (and its synonym
saxon:output) are replaced by
xsl:result-document. This no longer includes the serialization attributes directly, instead it refers by name to an
xsl:outputdeclaration, or can use the unnamed
xsl:outputdeclaration by default.
xsl:outputelement now supports
method="saxon:xhtml". The precise details of the output may not be fully conformant with the specification.
xsl:destinationelement is provided, however, since the
hrefattribute is currently ignored, it is not very useful at this stage.
saxon:handlerelement is no longer supported.
xsl:scriptelement is no longer supported - however, the synonym
collationattribute has been added to
xsl:sort, and the implementation of sorting now uses JDK 1.2 collators. The
collationattribute must match the name attribute of a
saxon:collationelement. If none is specified, the
langattribute is now used to select a collator, or if the
langattribute is omitted, a collator is obtained for the default locale.
xsl:sort-keyelement. A named sort key may be used to perform a sort from within an XPath expression, using the new XSLT-defined
I have made the following changes to the function library:
saxon:distinct()extension function now works on any sequence.
sum()functions now ork on any sequence, and new functions
lower-case(). These use the rules defined by the Java default locale
saxon:range()extension function (it can now be done using the syntax "a to b")
saxon:tokenize()to return a sequence of strings instead of a node-set
key()so that the second argument can be any sequence; each member of the sequence is converted to a string and treated as a potential key value
document()so that the first argument can be any sequence; each member of the sequence can be a URI of a document to be loaded.
saxon:node-set()extension function, which is now obsolete.
saxon:if()extension function, which is superseded by XPath 2.0 conditional expressions.
saxon:closure()function is temporarily withdrawn, because it relies on non-standard use of the
node-set()function in the EXSLT common module is now a no-op; the object-type() function returns one of "sequence", "boolean", "number", "string", or "external".
lowest()in the EXSLT
mathmodule to work on arbitrary sequences.
not3()(three-valued not() function)
saxon:for-all(): these are superseded by the
everyconstructs in XPath 2.0
compare()function: the third argument (collation) is initially mandatory, and must be a QName matching a
base-uri()function replacing the undocumented
float()is the only way of creating a single-precision floating point number.
In general, features of XSLT 2.0 and XPath 2.0 not listed above have not been implemented. In particular, these include:
As might be expected, the Saxon code has undergone major change internally, which will affect any application making significant use of internal interfaces. Here are some of the highlights:
forexpressions. It is also used in various other contexts, e.g. in the implementation of the document(), key() and id() functions.
getStringValue, this allows both SimpleValues and Nodes to implement the new Item interface, which represents a member of a sequence.
net.sf.saxon.value, now contains all the data-type related classes.
I have removed documentation of the saxon:trace extension attribute; it seems this hasn't been working for some time.
Contextclass no longer implements the XSLT 1.1 WD interface org.w3c.xsl.XSLTContext.
com.icl.saxon.handlers(ElementHandler etc). It is still possible for a Java application to register a NodeHandler to receive events; this must now be written as an implementation of the net.sf.saxon.NodeHandler interface. See the ShowBooks.java sample application to see how.
langattribute of xsl:sort; instead, it must be specified using the
collationattribute, with a
saxon:collationelement that maps the named collation to a Java class that implements the JDK
sql:query instruction has been added, to accompany the
|table||The table to be queried (the contents of the FROM clause of the select statement). This is mandatory, the value is an attribute value template.|
|column||The columns to be retrieved (the contents of the SELECT clause of the select statement). May be "*" to retrieve all columns. This is mandatory, the value is an attribute value template.|
|where||The conditions to be applied (the contents of the WHERE clause of the select statement). This is optional, if present the value is an attribute value template.|
|row-tag||The element name to be used to contain each row. Must be a simple name (no colon allowed). Default is "row".|
|column-tag||The element name to be used to contain each column. Must be a simple name (no colon allowed). Default is "col".|
xsl:query instruction writes zero or more row elements to the current
result tree, each containing zero or more column elements, which contain the data values.
Thanks to Claudio Thomas [email@example.com] who supplied the original version of this code.
The SQL extensions are now contained in a separate JAR file,
which must be on the class path if these extensions are used.
Michael H. Kay
30 April 2002