Internal changes
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.
The ContentEmitter
class now declares its methods with throws SAXException
, making life
easier for users who want to define a subclass.
Tail calls of named templates are now optimized not only for a directly recursive call, but for any
other call. So mutually-recursive templates now also benefit from this optimization, which means that
deep recursion is possible without running out of stack space. Tail calls using xsl:apply-templates
are also now optimized. The benefit applies only to the last call when a node-set is being processed,
but this is a typical use case with a call such as
<xsl:apply-templates select="following-sibling::*[1]"/>
.
However, tail calls of recursive stylesheet functions are not being optimized at the moment. The change in processing model (functions are now made up of instructions rather than expressions) made this too difficult. Reinstating this feature (introduced in 7.4) will require some kind of integration between the XSLT and XPath parts of the compiler.
The change in the way tail recursion is handled requires a change to the implementation of extension elements. A class that extends the Instruction class must now provide the methods processLeavingTail() instead of process(). No change is required other than declaring the return type as TailCall, and actually returning null.
Calls to xsl:function
are now notified to the TraceListener.