[xsl] [ANN] Saxon 9.9

Subject: [xsl] [ANN] Saxon 9.9
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 27 Sep 2018 18:12:26 -0000
With apologies if you get this on more than one list.

Saxon 9.9 is now available, from the usual locations -
http://www.saxonica.com/download/java.xml.

Specifically, Saxon-HE, Saxon-PE, and Saxon-EE are available for the Java
platform. The .NET version will follow.

Saxon 9.9 requires Java 8.

Full details are available in the change log at
http://www.saxonica.com/documentation/index.html#!changes , but here are the
main highlights:

(1) There's a significant extension of the s9api interface to provide XDM tree
navigation. Under the hood, this takes advantage of Java 8 streams. As an
alternative to using XPath expressions such as

XdmValue selectedBooks = xpath.evaluate("//book[author='" + key + "']", doc);

you can now write

doc.select(descendant("book").where(eq(child("author"), key)).asXdmValue();

There's a usability benefit because you're only using one language (Java)
rather than two (Java+XPath), and there's a performance benefit because it
cuts out the expensive XPath parsing stage. It also reduces the risk of
injection attacks, and is likely to detect more programming errors at compile
time. To make this work, we're now requiring a baseline of Java 8.

(2) Tuple types extend the XPath type system to provide better type checking
of complex data structures. If you're representing employee data as a map,
then instead of declaring it as map(xs:string, item()*), you can now declare
it as tuple(empNr: xs:string, dob: xs:date, name: element(personalName)). The
result is more readable code, better type checking (meaning faster debugging),
and better performance. The extension has been implemented in such a way that
it can be used without compromising the portability of your code to other XSLT
3.0 processors.

(3) Arrays, like maps, now have an internal implementation that means updates
to individual entries in the array don't require the whole array to be copied,
giving substantial performance improvements for applications that use arrays
heavily.

(4) Improvements have been implemented to the TinyTree data structure to
further reduce memory usage, and to enable zero-cost copying of subtrees from
one tree to another in the course of a transformation.

(5) A number of powerful new extension instructions and functions are provided
to enable easier query and update of the trees of maps and arrays that
typically arise when processing JSON input. For example, the instruction
<saxon:deep-update root="json-doc('empData.json')"
select="?*[?customer='Jones']?orders" action="array:append($order)"/> reads
and parses a JSON file, adds a new order for a selected customer, and returns
a data structure representing the modified data set, which can then be
serialized using the JSON output method.

(6) Streamed accumulators, as defined in the XSLT 3.0 Recommendation, are
extended with a new feature: by annotating an accumulator rule with the
attribute saxon:capture="yes", an entire element from the source document can
be captured as the value of the accumulator. For example this can be used to
capture the header section at the start of a document and make it available
for reference while the rest of the document is processed using pure
streaming.

(7) The updating primitives of the XQuery Update specification are now
available for use in XSLT via Saxon-defined extension instructions. These make
many simple updates (such as "delete all comments") easier to express and
faster in execution, without sacrificing the declarative nature of the XSLT
language. For a future release we are thinking about new data structures that
make such updates very efficient, avoiding the need to copy all the data in
the source document that has not changed.

(8) The XPath lookup operator "?" has been exploited to provide easier
call-out from XSLT and XQuery to Java code. For example, if the variable
$connection holds a SQL database connection obtained using the sql:connect()
extension function, then the expression $connection?isClosed() calls the Java
method isClosed defined on the underlying connection object.

(9) The ability for an XSLT stylesheet to produce "raw" output (for example, a
sequence of integers rather than an XML document), as envisaged in the XSLT
3.0 specification, is now much better supported in the Saxon API. A new
<code>RawDestination</code> is available to define the destination of a
transformation. Internally, there has been a significant tidying-up of the
interface between the transformation engine and a destination such as a
Serializer.

(10) There have been further improvements to diagnostics on type errors. This
applies especially when passing complex data structures between templates and
functions using maps. In general, instead of telling you that the expected
type was X but the supplied value V was an instance of Y, the message now
tells you in what way V fails to conform to the type X: for example, if X is
map{xs:string, node()} and V contains an entry whose key is of type
xs:untypedAtomic, then the error message in 9.8 would tell you that V is an
instance of map{xs:anyAtomicType, node()}, while 9.9 will tell you that V is
not an instance of map{xs:string, node()} because it contains a key whose type
is xs:untypedAtomic and whose value is (say) "Idaho".

Michael Kay
Saxonica

Current Thread