Saxonica: Saxon-JS release notes

Saxon-JS Release Notes

Maintenance release 2.2

11 May 2021

Bug fixing maintenance release.

For use with Saxon-JS 2, SEFs must be produced with Saxon-EE 10.0 or later, or compiled using the internal compiler in Saxon-JS 2 on Node.js.


See the Change History section of the documentation for full details.

The most significant change in this release is that Saxon-JS running on Node.js no longer creates a “SaxonJS” global object. This has two consequences:

  1. Saxon-JS works better in environments where the global object space is managed more strictly. In particular, it will work with Electron (see bug 4639) and tools like Webpack (bug 4669).
  2. If your Node.js application relies on the implicit creation of the SaxonJS global object, you will need to make a few minor changes to your application.

Bug fixes

  • Bug #4639: SaxonJS in Electron appears non-standard
  • Bug #4641: xpath-default-namespace not being honoured on ixsl:*/@object
  • Bug #4669: SaxonJS object is empty using Webpack
  • Bug #4768: fn:transform(): source-node and global context item
  • Bug #4913: Documentation/code discrepancy in regex flag for using the JavaScript RE engine
  • Bug #4923: The -xp option on xslt3.js should also support -json
  • Bug #4925: The -s option resolves spaces incorrectly in filenames
  • Bug #4958: saxon-js 2.1: Crash in Saxon.XPath.evaluate with certain predicates
  • Bug #4963: Missing namespace prefix in imported stylesheet is not detected
  • Bug #4978: a.ha is not a function

Maintenance release 2.1

2 March 2021

Bug fixing maintenance release.

For use with Saxon-JS 2, SEFs must be produced with Saxon-EE 10.0 or later, or compiled using the internal compiler in Saxon-JS 2 on Node.js.


See the Change History section of the documentation for full details.

The following new features have been added:

  • In the SaxonJS.transform() API, it is now possible to supply the principal input as a JSON document, rather than an XML document. The new option, sourceType, should be used to indicate that the supplied source is JSON.
  • Correspondingly, on Node.js, the command line option -json has been added as an alternative to -s. It allows the principal input to be a JSON document.
  • On Node.js, the -xp command line option has been added somewhat experimentally to allow an XPath expression to be evaluated directly over an XML document.
  • On the browser, the set of Window events that an XSLT event handler can respond to has been extended to include the resize and focus events (see also bug #4728.)

Bug fixes

  • Bug #4583: Failed to compile "('0', 0)[1] ! xs:integer(.)"
  • Bug #4584: document-uri() applied to initial source document gives no result
  • Bug #4587: use of undefined system property like system-property('product') gives Internal error: bad input to string constructor
  • Bug #4588: xsl:initial-template seems to be executed by fn:transform called from SaxonJS.XPath.evaluate although options set initial-match-selection and global-context-item
  • Bug #4589: Command line with no -o option: files written to parent of working directory
  • Bug #4590: xsl:result-document writing to file containing spaces
  • Bug #4596: XML output has empty line between XML declaration and root element
  • Feature #4598: Recognize exslt:node-set() extension function
  • Bug #4601: Problem with namespaces containing "="
  • Bug #4603: format-number() - grouping separator before any digit character
  • Bug #4607: Transformation failure from XX-compiled SEF for Saxon-Forms
  • Bug #4608: Reading JSON resource over HTTP: TypeError: c.codePointAt is not a function
  • Bug #4611: XPath expression "function(){'x'}()" crashes with TypeError: this.closureContext.localVars.slice is not a function
  • Bug #4612: XPath expression "function($x){true()}(17)" crashes "$elaborate$$ is not a function"
  • Bug #4613: Map is not substitutable for Function
  • Bug #4616: default-collation
  • Bug #4619: XX Compiler failure with static parameters whose type has an occurrence indicator
  • Bug #4622: Adaptive serializer fails when outputting a single attribute node
  • Bug #4624: Matching with namespaces in SaxonJS / NodeJS
  • Bug #4625: Representation of xs:base64Binary and xs:hexBinary
  • Bug #4629: Failure in key() function (originally from David Carlisle's HTML parser)
  • Bug #4634: In regular expressions, \W matches 'a'
  • Bug #4660: Incorrect xpath-default-namespace on included files with XX compiler
  • Bug #4681: namespace declaration not honored: error XTDE1390 undeclared prefix: saxon
  • Bug #4686: XSLT 3 using fold-left fails in Saxon-JS 2 with error Expected mode, found function
  • Bug #4690: generate-id problem when chaining stylesheets and storing intermediary results as a tree
  • Bug #4702: CR (x13) under node.js
  • Bug #4723: XSLT 3 using function-lookup gives TypeError: h is not a function
  • Bug #4725: Saxon-JS 2 fails to compile XSLT stylesheet giving error "Required cardinality of value of parameter $static-base-uri is exactly one; supplied value is empty"
  • Bug #4728: Coverage for event handling
  • Bug #4734: SaxonJS.transform nonInteractive option does not work
  • Bug #4742: innermost() - nodes missing from result
  • Bug #4743: Performance: substring() and subsequence()
  • Feature #4748: Option to supply Accept header in SaxonJS.getResource()
  • Bug #4754: xs:decimal idiv operator (suspicious code)
  • Bug #4756: Failure XTTE3090 with on-no-match=deep-skip
  • Bug #4757: Casting from xs:date to xs:dateTimeStamp
  • Bug #4758: Casting large xs:decimal values to xs:integer
  • Bug #4762: Function conversion rules in option parameters conventions
  • Bug #4767: xsl:with-param value evaluation in xsl:call-template in ixsl:schedule-action
  • Bug #4776: Arithmetic in backwards compatibility mode
  • Bug #4777: Shadow attribute xsl:include/@href
  • Bug #4778: snapshot() function applied to a namespace node fails with internal error
  • Bug #4779: Bad command line parameters cause internal error and stack trace
  • Bug #4780: UntypedAtomic to xs:double conversion does not happen for a dynamic call to fn:abs#1
  • Bug #4781: Higher-order functions: No failure reported when supplied function doesn't match required signature
  • Bug #4783: Incorrect results when comment node is created as child of document node
  • Bug #4785: fn:path() for parentless element node gives /Q{}foo[1]
  • Bug #4787: Map failures with temporal keys using timezones under advanced closure compilation
  • Bug #4802: Overzealous optimization
  • Bug #4804: Failure in XX compiler, incorrect type inferencing
  • Bug #4805: Command line: -s option with HTTP or FILE uri
  • Feature #4806: Transforming JSON input
  • Bug #4818: fn:sort with three arguments gives error TypeError: d.compareTo is not a function
  • Bug #4830: HTML response from ixsl:schedule-action is parsed as XML, causing failure
  • Bug #4843: js:history.pushState() has no effect?
  • Feature #4844: Could 'resize' be added to the list of windowEvents?
  • Bug #4852: SaxonJS incorrectly URI encodes 'value' attributes on 'input' elements
  • Bug #4863: If the root element is an empty element, it is not serialized correctly
  • Bug #4877: AssertionError: TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Array

Major release 2.0

12 June 2020

Saxon-JS 2 is a major upgrade from the previous Saxon-JS 1 releases. The most obvious changes are:

  • The product is now available on Node.js as well as in the browser.
  • The product now includes an XSLT compiler as well as a run-time, so it is no longer restricted to users who have purchased a Saxon-EE license.

But there's also a vast number of smaller changes:

  • A serializer with a very high level of conformance to the W3C specifications.
  • A richer JavaScript API both for XSLT transformations and XPath evaluation.
  • Support for higher-order functions.
  • General filling in of remaining conformance gaps, taking us to 99.9% coverage of XSLT 3.0 and XPath 3.1.
  • Significant performance enhancements.

We're very excited by the potential of this product. Node.js has become a very popular platform for high-performance web services, and until now it has had rather poor support for XML technologies generally, and XSLT in particular. Saxon-JS on Node.js is effectively a brand new XSLT processor, which can now operate completely independently of the Java product. Our initial performance results are very encouraging indeed.

For use with Saxon-JS 2, SEFs must be produced with Saxon-EE 10.0 or later, or compiled using the internal compiler in Saxon-JS 2 on Node.js.


See the Change History section of the documentation for full details.

Bug fixes

  • Bug #3132: Composite keys in xsl:key not implemented
  • Feature #3238: Non-interactive stylesheets
  • Bug #3387: Inverse character ranges in regular expressions
  • Bug #3413: Test accumulator-014 fails "Invalid local name"
  • Feature #3420: xsl:global-context-item is not implemented
  • Bug #3422: Failure to report XTDE3052
  • Bug #3423: Incorrect binding to modes by name
  • Bug #3424: Two keys with same name in different packages
  • Bug #3425: Cannot handle more than two packages
  • Bug #3435: Function call to xsl:original() is not supported
  • Bug #3436: Two accumulators with same name in different packages
  • Bug #3461: Asynchronous fetch for other external resources
  • Feature #3462: Asynchronous fetch for internal resources
  • Bug #3535: initial-function parameters are not type-checked
  • Bug #3561: generate-id() on attribute and namespace nodes may produce a non-ASCII string
  • Feature #3569: Test if a Javascript property exists before calling ixsl:get()
  • Feature #3570: Add a function or instruction like ixsl:remove-property
  • Feature #3572: Have an extra attribute for ixsl:set-attribute to select the element to be affected
  • Feature #3589: Saxon-JS should depend only upon JavaScript, not web browsers
  • Bug #3899: Incorrect handling of mixed backward-compatibility xsl:key
  • Bug #4103: Saxon-JS dynamic loading errors - it won't run on Tizen OS in a webapp browser (on Smartwatches and TVs)
  • Bug #4116: Cannot load SEF stylesheet under NW.js
  • Bug #4174: No response body from HTTP request when http.status >= 400
  • Bug #4176: parse-xml() in Saxon-JS loses html namespace
  • Bug #4191: Saxon-JS error on null Content-Type
  • Bug #4424: Arithmetic with large integers

Maintenance release 1.2.0

5 October 2018

Bug fixing maintenance release. Primarily fixes to allow Saxon-JS to work correctly with SEFs produced with Saxon 9.9.

In general for use with Saxon-JS 1.x, SEFs should be produced with Saxon-EE or later, though to be able to use all new features since Saxon-JS 1.1 it is recommended that SEFs are produced with Saxon-EE or later.


  • SEFs produced using Saxon-EE 9.9 require Saxon-JS 1.2.

Bug fixes

  • Bug #3783: Incorrect evaluation of ?* on arrays
  • Bug #3790: Saxon-JS documentation app search problems
  • Bug #3813: Should add err= to the list of conventional namespace bindings
  • Bug #3833: Problems using fn:replace() with special characters in replacement string
  • Bug #3865: Issues running 9.9 SEFs with Saxon-JS 1.1.0
  • Bug #3869: Missing run time type check for value comparisons for xs:qname and xs:duration
  • Bug #3870: Mishandled "undefined" in code for filter expression
  • Bug #3910: Error using fn:replace() with "q" flag when search string contains "-" character
  • Bug #3944: fn:innermost() expects input sequence to be in document order

Maintenance release 1.1.0

9 May 2018

Bug fixing maintenance release.

In general for use with Saxon-JS 1.x, SEFs should be produced with Saxon-EE or later, though to be able to use all new features of Saxon-JS 1.1 it is recommended that SEFs are produced with Saxon-EE or later (beware the ixsl:schedule-action/@wait bug #3734 in and


See the Change History section of the documentation for full details. Below is a summary:

  • Changes have been made to the way that JavaScript objects are converted to XDM, and the way that XDM maps are converted to JavaScript. See JS/XDM Type Conversion and Supplying stylesheet parameters for up to date details.

  • Serialization to JSON is implemented (with some restrictions).

  • Added two ways to set the logging level for warnings, processing messages, or full tracing, using the Saxon-JS API: the API method SaxonJS.setLogLevel, and the SaxonJS.transform option logLevel.

  • Additions to the SaxonJS.transform API: templateParams and tunnelParams to allow parameters to be supplied for call-template invocation.

  • The extension instruction ixsl:schedule-action has been updated to allow document fetches and HTTP requests to be terminated: either using a timeout, or by user initiated abort. Requires Saxon-EE or later at compile time. See HTTP request termination for more information and examples.

  • Some Saxon extension functions are now available in Saxon-JS (see Saxon extensions): saxon:discard-document() and saxon:timestamp().

Bug fixes

  • Bug #3223: Supplying Document objects to JavaScript global functions
  • Bug #3378: result-document doesn't handle AVT for method
  • Bug #3379: regex-group() value is not maintained through calls of xsl:apply-templates and xsl:apply-imports
  • Bug #3381: Spurious "unmatched ')'" error in regular expression
  • Bug #3475: Problem with SEF generated using Oxygen 19.1 "Compile XSLT Saxon 9.8" add-on
  • Bug #3499: Keys should be invalidated if the (relevant part of the) HTML page is updated
  • Bug #3500: ixsl:event() does not correctly return an empty sequence when there is no current event
  • Bug #3501: Error when object supplied to ixsl:get() is null
  • Bug #3502: ixsl:source() does not correctly return an empty sequence when there is no global context item
  • Bug #3544: Third argument of ixsl:call() is an array, documentation is inconsistent
  • Bug #3545: Inconsistencies using map functions on JS objects
  • Bug #3564: Check that context item is an element for ixsl:set-attribute and ixsl:remove-attribute
  • Feature #3568: Add a way to cancel a scheduled action
  • Feature #3571: Have some equivalent of saxon:discard-document
  • Bug #3596: current-date and current-dateTime does not give the instant date/time stamp
  • Bug #3611: Handle error responses from HTTP requests
  • Bug #3670: Implement more transform options
  • Bug #3676: Implement serialization to JSON
  • Bug #3689: Problem with apply-templates in "#current" mode
  • Bug #3704: Issues with ixsl:style()
  • Bug #3718: Mishandling null, undefined, and array results from ixsl functions
  • Bug #3727: Edge browser problem for script elements dynamically added to page
  • Bug #3738: Cannot set properties to null using ixsl:set-property
  • Feature #3741: Allow users to configure message logs
  • Bug #3756: Stack overflow in base64_decode()

Maintenance release 1.0.2

5 October 2017

Bug fixing maintenance release.

In general for use with Saxon-JS 1.0 SEFs should be produced with Saxon-EE or later, though a number of features introduced in Saxon-JS 1.0.1 require SEFs produced with Saxon-EE 9.8 (see the documentation for details).


  • A space-separated list can now be supplied in the document attribute of ixsl:schedule-action, to fetch multiple documents before the contained call is invoked.

Bug fixes

  • Feature #2889: Missing error trapping in Calculate
  • Bug #3268: Saxon-JS documentation app problems in Safari on iPad (and other handheld devices)
  • Bug #3362: reverse() modifies its argument
  • Bug #3369: Incorrect test for node identity in p.genNode pattern matching
  • Bug #3370: currentGroup / currentGroupingKey
  • Bug #3377: HTML base tag ignored in stylesheetLocation and sourceLocation
  • Bug #3380: xsl:analyze-string with a regex that matches a zero-length string
  • Bug #3383: General Comparison in 1.0 compatibliity mode: cannot compare xs:string with xs:integer
  • Bug #3386: deep-equal() fails comparing attributes
  • Bug #3393: "<" treated as entity characters within XPath.evaluate()
  • Bug #3417: unparsed-text-lines() incorrect behaviour with blank lines
  • Bug #3419: format-number() rounding issues
  • Bug #3431: non-default exponentSeparator character not interpolated
  • Bug #3440: Handling asynchronous document fetch failures
  • Feature #3441: Asynchronous fetch for a list of documents
  • Bug #3442: Problems reusing parameters after ixsl:schedule-action
  • Bug #3454: Documentation for ixsl:schedule-action/@http-request
  • Bug #3470: SaxonJS 1.0.1 fails when calling the key() function; SaxonJS 1.0.0 works well

Also includes a patch for a known Edge bug related to regular expressions used in reading XML resources (see Forum issue #6873).

Maintenance release 1.0.1

21 July 2017

Maintenance release for use on web browsers. A number of new features require SEFs produced with Saxon-EE 9.8 (in general SEFs should be produced with Saxon-EE or later for use with Saxon-JS 1.0).


  • Many more XSLT 3.0 features are now implemented. Some require Saxon 9.8 at compile time. See conformance for full details. Newly implemented features include:
    • xsl:where-populated, xsl:on-empty, xsl:on-non-empty, xsl:fork
    • snapshot(), available-system-properties()
    • use of initial mode "#unnamed"
    • accumulators (requires Saxon 9.8)
    • collection() (requires Saxon 9.8)
    • merging (requires Saxon 9.8)
    • multiple packages (requires Saxon 9.8)
    • xsl:source-document in non-streaming mode (requires Saxon 9.8)
    • xsl:context-item (requires Saxon 9.8)
    • Support for collations has been extended to XSLT instructions as well as XPath functions
    • Regex character class subtraction
    • Fixes for xsl:evaluate (default XPath namespace; support for @as result type restriction; support for xsl:with-param in addition to @with-params)
  • Additions to the SaxonJS.transform API: initial-function and function-params to allow function call invocation; collations to supply collations; collectionFinder to supply collections.
  • The SaxonJS.transform() option initial-mode set to "#unnamed" can be used to force use of the unnamed mode. If initial-mode is not set, then the default-mode specified in xsl:stylesheet (or xsl:package) is used, defaulting to the unnamed mode.
  • Added interactive XSLT mechanism for making asynchronous HTTP requests directly from the stylesheet - using the new http-request attribute on ixsl:schedule-action (requires Saxon 9.8). See HTTP messages for more information.
  • Using Saxon 1.0.0 or earlier, URIs in the doc() function and in the document attribute of ixsl:schedule-action were always interpreted relative to the SEF's location. In Saxon-JS 1.0.1, the behaviour depends on whether the SEF is relocatable, since this will determine the static-base-uri(). From Saxon 9.8, a relocatable SEF can be produced by setting the Transform command line option -relocate:on at compile time. If the SEF is relocatable, then static-base-uri() is the base URI of the SEF; otherwise it is the location of the XSLT stylesheet at compile time. For full details see the section about relative URIs at Source documents.

Bug fixes

  • Feature #3004: Support for HTTP POST/PUT
  • Bug #3036: Saxon-JS documentation app problems in Chrome on computers with touch screens
  • Bug #3066: Specialist name() treatment of XHTML elements
  • Bug #3130: Source document has a non-absolute base-uri()
  • Bug #3131: XPath.evaluate - incorrect comparison typing for xs:QName
  • Bug #3133: xs:numeric cast not preserving value type
  • Bug #3134: map:get() key not being atomised
  • Bug #3139: Complex Content incorrectly handing text-nodes
  • Bug #3140: XPath.evaluate should check initial context-item cardinality
  • Bug #3146: system-property("xsl:supports-dynamic-evaluation") returns "no"
  • Bug #3148: xsl:evaluate doesn't support use of user-defined functions
  • Bug #3149: Constructed element node lacks xmlns="" undeclaration
  • Bug #3161: || operator in dynamic XPath does no type checking
  • Bug #3167: Problems with QName hash-codes in trieWithCollation()
  • Bug #3170: Attributes with no prefix in name get assigned 'ns'
  • Bug #3187: Printing
  • Bug #3203: Default namespace XHTML not appearing in namespace-uri-from-prefix()
  • Bug #3216: Error QNames are not ordered
  • Bug #3221: p.genPos pattern not implemented in Saxon-JS
  • Bug #3231: Default treatment of Atomic items in text-only-copy incorrect
  • Bug #3335: Lazy evaluation of sequence constructors - instructions with side effects evaluated early

Major release 1.0.0

7 February 2017

First major release, for use on web browsers. For use with Saxon-JS 1.0, SEFs should be produced with Saxon-EE or later.


  • For use with Saxon-JS 1.0, SEFs should be produced with Saxon-EE or later. (Most SEFs produced by older versions of Saxon-EE will run as before, but some will fail with an error directing the user to regenerate the SEF.)
  • Added Dynamic XPath evaluation for use with xsl:evaluate, and directly via the XPath API.
  • The use of collations in XPath functions is now implemented, see Conformance for details (and restrictions).
  • Known performance issues have been addressed.

Bug fixes

  • Bug #3071: Bad performance of xsl:result-document with deeply nested output content
  • Bug #3095: XPath.evaluate requires platform initialisation
  • Bug #3098: Supplied value "..." is not a valid xs:base64

Maintenance beta release

12 December 2016

Maintenance release for use on web browsers.

Bug fixes:

  • Bug #3067: Specialist name() treatment of XHTML elements

Maintenance beta release 0.9.1

9 December 2016

Maintenance beta release for use on web browsers (Safari, Firefox, Chrome, Opera, Internet Explorer, and Edge). This release can be used with SEFs produced by Saxon-EE or later, but for all the latest features use Saxon-EE or later.


  • The form <xsl:result-document href="?."> can now be used to specify the current context as the target for inserting generated HTML fragments, see Result documents.
  • Added support for the transform options sourceNode and sourceText, see SaxonJS.transform.
  • Values for stylesheet parameters with type map(*) and array(*) can now be supplied using the transform option stylesheetParams (requires Saxon-EE or later). See Supplying stylesheet parameters.
  • The interactive XSLT function ixsl:apply() is added (requires Saxon-EE or later).
  • The XSLT 3.0 xsl:iterate and xsl:evaluate instructions are now implemented (requires Saxon-EE or later).
  • The third-party URI.js library is no longer used.
  • Extended browser support: Saxon-JS 0.9 tested with current versions of Safari, Firefox and Chrome; Saxon-JS 0.9.1 also tested with Internet Explorer, Edge and Opera.

Bug fixes

  • Bug #2752: JS: nashorn references in core (browser) code
  • Bug #2796: JS: xs:date() can modify timezone for pure dates
  • Bug #2833: JS: anomalous descendant behaviour under ixsl:page()
  • Bug #2884: Registering event listeners for objects outside DOM
  • Bug #2885: Use of URI.js
  • Feature #2886: Converting JS Objects to XDM maps
  • Bug #2888: Static base-uri for in-browser exported stylesheets.
  • Bug #2890: document.createAttributeNS() deprecated - warning in Firefox
  • Bug #2891: Checksum in SEF file
  • Bug #2913: does not work with Edge
  • Bug #2923: Incorrect comparison for xs:numeric and NaN
  • Bug #2941: Crash when there is no context item
  • Bug #2942: Failure to specify -target:JS
  • Bug #2944: Use of xsl:sequence within copy situations is node-destructive
  • Bug #2945: for-each-group context not being preserved over context-altering steps
  • Bug #2947: Cities List example
  • Bug #2948: SEF metadata
  • Feature #2966: xsl:iterate
  • Bug #2992: treat as not testing sequence cardinality
  • Bug #3007: sourceNode or sourceText property of options argument of transform method not used
  • Bug #3008: ixsl:query-params() does not allow for multiple values associated with a single field
  • Bug #3012: In browser, do not always produce HTML elements in result documents when they should be produced
  • Bug #3020: _APPLY() construct has not been implemented in Saxon-JS

First beta release 0.9

28 July 2016

First beta release for use on web browsers with SEFs produced by Saxon-EE or later.