Saxonica: Saxon-JS release notes

Saxon-JS Release Notes

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.