SAXON home page

Changes in this Release

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.

Changes in version 7.6 (2003-06-22)

Defects cleared

755834Stack overflow error when xsl:with-param depends both on the context node and on variables

759502The getOutputProperty() and getOutputProperties() methods of the Transformer object always return null

XSLT Changes

Added the as attribute to xsl:template. (This is not a very efficient implementation, as it breaks the pipeline) {seq017, seq906err, seq907err}

The [xsl:]default-xpath-namespace attribute is renamed [xsl:]xpath-default-namespace.

Two local variables in the same template or function can now have the same name. But parameters must still have unique names. (A side-effect of this change is a useful improvement in compilation speed for stylesheets with many global variables. The checking done in previous releases was implemented very inefficiently.) {var13, var901err}

I have added type-checking for global (stylesheet) parameters. It's not entirely clear here what the rules ought to be. Somewhat pragmatically, I have adopted the rule that if you supply a string (which will always be the case if parameters are provided on the command line), then the system attempts to convert it to the type specified in the xsl:param declaration; if you supply anything else, then it must (after Java to XPath conversion) be of exactly the required type, without any conversion.

XQuery

Saxon now supports XQuery. Details of how to use XQuery are provided at using-xquery.html, and information about the conformance to current working drafts is in conformance.html.

Function Library

The doc function is implemented.

The trace function has been changed so that it is never evaluated at compile time, even if both arguments are constants.

Internal Changes

The optimization of count($x)=0 as empty($x) was working only when the stylesheet specifies version="2.0". It now works with version="1.0" also.

Text-only temporary trees are used in a wider range of circumstances than before. This data structure is used when it is known statically that a temporary tree will consist of a single text node; it is a lot more efficient than a general-purpose temporary tree. It is now used in cases where the content of the variable invokes xsl:text and xsl:value-of including calls that are within xsl:for-each, xsl:choose, xsl:if, xsl:sequence and xsl:analyze-string, and also where it uses xsl:call-template, provided that all the subordinate instructions generate text nodes. This has been done in a generalized way which will eventually lead to static type inferencing working at the XSLT level in the same way as it currently works at the XPath level. For xsl:template, the type of the results is inferred from the as attribute if present, or from the contents of the template otherwise. {not v. thoroughly tested!}

Range variables (that is, variables declared in an XPath expression (for, some, every) are now stored on the local stack frame in the Bindery rather than directly in the XPathContext object. This simplifies the machinery for handling variables and allows instructions and expressions to be treated more interchangeably.

The Expression class has been refactored. The original class net.sf.saxon.expr.Expression is now an interface. The various expressions are now structured under ComputedExpression for "true" XPath expressions, net.sf.saxon.value.Value for constant values, and InstructionExpr for instructions (such as xsl:element) that act as expressions when used from XQuery. The utility methods, including the make factory method, are now in net.sf.saxon.expr.ExpressionTool.

When the dependencies of a ComputedExpression are determined, the information is now saved with the expression rather than being recalculated whenever it is needed. For complex expressions this calculation can be quite complex, and there are still some cases where it is being done at run-time.

Path expressions now use the standard type-checking machinery to check that both arguments of "/" are node-sets. This means that in some cases an error in this area will now be detected statically; and it means that if the expression is found statically to be safe, no run-time checking is done.

I have changed the way delayed evaluation is done: when an expression is evaluated lazily, a Closure object is created as a surrogate for the value. This now contains the expression itself together with all the context information that the expression needs. The separate SavedContext object is no longer used. The Closure is evaluated using the ordinary XPathContext object, which now holds a reference to the local stack frame. With delayed evaluation, this "stack frame" is not actually on the stack at all, it is in the heap, so it survives if the Closure is returned from a function call.

I have reverted to the principle used prior to Saxon 7.x, that lazy evaluation is used only for expressions that are expected to return a (non-singleton) sequence. However, the classification of such expressions is now much more accurate. The reason for this policy is that delaying evaluation of singleton expressions is usually not beneficial - it saves no memory, and incurs a cost for saving and restoring the context. Also, lazy evaluation is not used for expressions that have unusual context dependencies, for example those that depend on current(), position(), last(), or current-group(). This eliminates the problem of saving these values and ensuring that they are referenced correctly during the delayed evaluation.

The delayed evaluation code now evaluates the underlying expression at most once, thus ensuring that it never takes longer than direct evaluation. At the same time, if only the first item in the sequence is used then only the first item will be read. In a construct such as if (exists($x)) then $x else "nothing", the first reference to $x primes the iterator, and saves anything it reads in a buffer (called the "reservoir") within the Closure object. The second reference to $x starts by reading what it can from the reservoir, and if it needs more, it picks up iterating the underlying expression where the first evaluation left off. Once some user of the variable has accessed all the items in the underlying expression, the reservoir contains all the values needed and subsequent evaluations read the value from there.

Certain instructions, specifically those that are used in for XQuery as well as XSLT processing, now act as expressions as well as instructions. There are two modes of evaluating these instructions: the process() method causes the instruction to write its output to the current Receiver, while the evaluateItem() and iterate() methods return the results in the same way as for any other expression.

To support this mechanism, the process() method now takes an XPathContext as its argument, instead of the Controller. This is because in XQuery, the XPath context needs to be passed unchanged by an element constructor to its child expressions.

Extension Functions

Thanks to Gunther Schadow for these changes.

If an extension function returns null, this is now mapped to a zero-length sequence rather than to an external object that wraps null. This prevents some run-time type failures.

Exceptions thrown by an extension function are now wrapped in the XPathException thrown by the calling XPath expression, and hence in the TransformerException thrown by the transformation as a whole.

Public fields in Java classes are now accessible as zero-argument functions, for example the field Double.MIN_VALUE is accessible as Double:MIN_VALUE() with the namespace prefix bound as xmlns:Double="java:java.lang.Double". Non-static fields can be accessed by including the object instance as the first argument. It is not possible (and rarely necessary or desirable!) to modify public fields without use of a setter method. {saxon74}

The extension function saxon:is-null (which was incorrectly documented as saxon:if-null) is now redundant, and is dropped.

The undocumented saxon:trace function is dropped: use fn:trace instead.

Changes in version 7.5.1 (2003-05-21)

Defects Cleared

A couple of bugs in tail recursion have been fixed:

736802Tail recursive calls are sometimes not executed

A couple of cases have been reported where stylesheet errors cause a crash, these have been fixed.

I have recently installed JDK 1.4.1: this has revealed a couple of problems/inconstencies. The new JDK release appears to fix some problems with regular expression handling and with use of collations. This means that some of my tests produce subtly different results. In one or two cases the new results are clearly wrong, which means that my code was relying on the incorrect JDK 1.4.0 behavior. I have made adjustments where it seems appropriate, but particularly with collations, it is not always obvious what the right answer is.

New functionality

It is now possible to have two or more stylesheet functions with the same name, provided they have the same arity (number of parameters). An error is reported if two functions have the same name, arity, and import precedence. {func27, func901err}

Added support for xsl:template mode="#all". {modes30-34, inimode002}

Basic support for the functions format-date, format-time, and format-dateTime is provided. The xsl:date-format declaration is not implemented, and the third argument of the function is ignored. Not all formatting options are supported, and timezones are not handled properly yet. {date67}

Documentation

I have done a lot of work on the JavaDoc documentation of key interfaces and classes, and some general code cleaning up (for example, removal of redundant methods).

Internal Changes

The classes representing character encodings (in package net.sf.saxon.charcode) are now singleton classes; they only ever have one instance.

Changes in version 7.5 (2003-05-02)

Defects Cleared

The following bugs are fixed in this release:

687946 An internal error may occur when the key function is used on the right-hand-side of the / operator in a path expression.

689934 A ClassCastException occurs when comparing two values that are not comparable according to XPath 2.0 rules, for example string and integer.

690736 An IllegalStateException may occur when a sequence-valued variable is promoted by the optimizer to move it outside a predicate. The specific message is: java.lang.IllegalStateException: evaluateItem called on non-singleton variable reference at net.sf.saxon.expr.VariableReference.evaluateItem(VariableReference.java:202)

700837 An expression that uses a range variable (for example, a for or some expression) cannot be used within a predicate in an XSLT pattern.

706935 A NullPointerException occurs when processing an expression of the form //x[$var] or .//x[$var].

708789 When two or more items have sort keys that evaluate to the empty sequence, the resulting sort order is incorrect.

708998 Incorrect recovery action when xsl:copy-of generates a non-text node in the value of an attribute, comment, or processing instruction.

709347 An empty sequence is not being converted to an empty string when calling a function in backwards compatibility mode.

710093 The value of position() is calculated wrongly when navigating an axis on a JDOM tree.

721687 Crash in XPathEvaluator (Java XPath API) due to incorrect generation of type-checking code.

722537 Saxon crashes if an attribute is marked as an ID but is not a valid ID, which can happen when using a non-validating parser.

Withdrawn Facilities

I have finally dropped support for the old Java-only event-driven API. This was starting to interfere with the ability to optimize XSLT processing. The XPath interfaces remain available. Indeed, all the internal APIs remain available, but I am no longer trying to keep them as simple or as stable as is necessary for a supported external API. There were serious bugs in the ShowBooks.java sample application in Saxon 7.4 that somehow didn't show up in testing; this sample application has now been dropped.

I have also finally been forced to drop preview mode. It no longer works because the optimizer is becoming too clever. The optimizer uses lazy evaluation of expressions, which relies on the fact that the source document is immutable; preview mode violates this assumption. The correct way to handle this requirement is to write a document splitter as a SAX filter, breaking the source document into small pieces and invoking one transformation for each piece.

The deprecated extension functions get-user-data() and set-user-data() are no longer documented, though they have not yet been deleted from the product.

XSLT Changes

The required="yes|no" attribute on xsl:param is implemented. Currently, failure to supply a required parameter is a dynamic error, it is never detected statically. {ntmp01, ntmp901err}

The xsl:next-match instruction is implemented. {cnfr24-27}

The error that occurs when the name attribute of xsl:element or xsl:attribute contains an undeclared prefix (in the absence of the namespace attribute) is now recoverable. This brings it into line with the handling of other errors in this value. Note however that if the name is known statically then the error is reported at compile time and is fatal.

The error that occurs when a namespace or attribute node is written using xsl:copy-of, when there is no open element start tag, is now recoverable. This brings it into line with other instructions such as xsl:attribute and xsl:copy. {copy62}

Sequence Construction in XSLT

Implemented the new facility to allow construction of sequences in XSLT, when a variable binding element has content and an as attribute.

Added the as attribute to xsl:function. {func20}

Implemented the xsl:sequence instruction, including the as attribute which checks the type of the returned sequence and performs any necessary (and permitted) conversions. {seqNNN}

The xsl:result element is withdrawn. It can always be replaced by xsl:sequence. The as attribute, which denotes the return type of the function, should preferably be moved to the xsl:function element.

Parentless attribute, text, comment, processing-instruction, and namespace nodes are implemented. They are probably a little fragile - some operations on such nodes (e.g. xsl:number, xsl:apply-templates) have not been tested. The new rules for match patterns with parentless nodes have not been implemented: it's probably best to avoid using apply-templates on such nodes for the moment. {seqNNN}

Some instructions, e.g. xsl:value-of, incorrectly generate multiple text nodes, some other instructions may pre-merge the text nodes.

Handling of document nodes within the constructed sequence is probably not yet correct.

The separator attribute of xsl:copy-of is withdrawn.

Revised syntax for validating result trees

The 2 May 2003 WD changes the syntax for attaching type annotations to nodes in a result tree. These facilities are only partially implemented in Saxon, and no new functionality is provided in this release, but the existing functionality has been converted to use the new syntax. Specifically: