Saxonica Developer Community: Issueshttps://saxonica.plan.io/https://saxonica.plan.io/favicon.ico2024-03-19T09:54:05ZSaxonica Developer Community
Planio SaxonJS - Bug #6374 (New): saxon.compile removed in 2.6+?https://saxonica.plan.io/issues/63742024-03-19T09:54:05ZJai B
<p>Hi,</p>
<p>I've always used the <code>saxon.compile</code> function to generate sef files in code. I know it's undocumented but IIRC it was shown in the command line docs or something.</p>
<p>Basically I cache the compiled sef so I don't have to recompile everytime I want to do a transform and I don't want to pre-transform my XSLT files on the command line, nor do I have any desire to use the Java version for that part, the JS compiler has worked amazingly!</p>
<p>My web app does server side transformations with node; anytime it sees the XSLT change, it runs a compile to generate and cache a new sef to use for subsequent transformations. I can't cache the result of the transformation either since the data is dynamic, of course.</p>
<p>Perhaps I'm missing something or missing some changes, but this has worked awesome for years and only just noticed things breaking when redeploying some stuff and npm updating to 2.6.0 and getting an error that the function doesn't exist.</p>
<p>When I was initially implementing this, I know I spent a fair bit of time trying to figure this part out and ensure I was doing things right; I think I scoped the code that generates the sef on command line to find the function in the first place and was surprised it wasn't actually documented/available anyway.</p>
<p>Thanks again for SaxonJS!</p> SaxonJS - Bug #6346 (New): NPE with replace() on SaxonJS2.6 when exported under 4.0-support condi...https://saxonica.plan.io/issues/63462024-02-14T14:05:50ZJohn Lumleyjohn@saxonica.com
<p>When exporting a stylesheet (either 3.0 or 4.0) for SaxonJS 2.6, using SaxonEE 12.4 running under <code> --allowSyntaxExtensions:on</code>,
a three-argument call on <code>replace()</code> (that is with the fourth <code>$flags</code> argument to default to the empty string), at runtime a null pointer expection is thrown when attempting to retrieve the flags:</p>
<pre><code class="javascript syntaxhl" data-language="javascript"><span class="kd">const</span> <span class="nx">flags</span> <span class="o">=</span> <span class="nx">args</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">?</span> <span class="nx">args</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="nx">next</span><span class="p">().</span><span class="nx">toString</span><span class="p">()</span> <span class="p">:</span> <span class="dl">""</span><span class="p">;</span>
</code></pre>
<p>The <code>next()</code> returns a null.</p>
<p>Without <code>allowSyntaxExtensions</code> or with the fourth argument supplied, the function behaves as expected.</p>
<p>Sample stylesheet, compiled SEF and web page attached</p> SaxonJS - Bug #6298 (New): base-uri() value does not update together with DOMhttps://saxonica.plan.io/issues/62982023-12-19T23:34:51ZMartynas Jusevicius
<p>My SaxonJS code replaces large chunks of DOM with content loaded from different documents. DOM's baseURI property returns the source document's URL, but <code>base-uri()</code> does not always seem to do that. Which can lead to a stale value, probably because the DOM is updated?</p>
<p>This is my observation of the discrepancy:</p>
<pre><code>ixsl:get(., 'baseURI'): https://localhost:4443/7b386331-5a82-46ab-820b-38df78a91456/ SaxonJS2.rt.js:785:84
base-uri(): https://localhost:4443/ SaxonJS2.rt.js:785:84
ixsl:location(): https://localhost:4443/7b386331-5a82-46ab-820b-38df78a91456/
</code></pre> SaxonJS - Bug #6250 (New): SyntaxError: Unexpected token '='https://saxonica.plan.io/issues/62502023-11-11T13:53:59ZPrasad Kuppa
<p>Hi Team,
Getting below error while running xslt3 from command line.</p>
<p>/usr/local/lib/node_modules/xslt3/node_modules/saxon-js/SaxonJS2N.js:4290
q("not a node"),Error.tg&&Error.tg(),q("wrong node kind "+p.nodeType)}const k=fc;a(E,"indent","boolean",!1);return d(u)}}}();const Td=function(){function a(r,g,e,n,y){e="xml"===e?g.fixed.gb:g.fixed.$b;g=g.fixed.hd;var u=e[r];if(!u||u instanceof H){u=g[r];if(!u){try{u=n()}catch(E){u=E}g[r]=u}u=y(u);e[r]=u}if(u instanceof H)throw u;return u}function b(r,g){g||="utf-8";r=void 0===r.Ob?r:r.Ob;if(g.startsWith("utf")&&0<=r.indexOf("\ufffd"))throw new H("External file contains non-Unicode characters","FOUT1190");return r}function h(r){if(0<=r.indexOf("\x00"))throw new H("External file contains non-XML characters","FOUT1190");
^</p>
<p>SyntaxError: Unexpected token '='
at wrapSafe (internal/modules/cjs/loader.js:915:16)
at Module._compile (internal/modules/cjs/loader.js:963:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (/usr/local/lib/node_modules/xslt3/xslt3.js:43:357)
at Object. (/usr/local/lib/node_modules/xslt3/xslt3.js:93:95)
at Module._compile (internal/modules/cjs/loader.js:999:30)</p>
<p>OS: Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-70-generic x86_64)
Node Version: v12.22.9
NPM Version: 8.5.1
SaxonJS Versions tried: 2.3.0, 2.4.0, 2.5.0 & 2.6.0</p>
<p>Thank you for your support.</p> SaxonJS - Bug #6245 (New): broken links in SaxonJS documentation https://saxonica.plan.io/issues/62452023-11-08T14:13:28ZMartin Honnenmartin.honnen@gmx.de
<p><a href="https://www.saxonica.com/saxon-js/documentation2/index.html#!conformance/xslt30" class="external">https://www.saxonica.com/saxon-js/documentation2/index.html#!conformance/xslt30</a> has (at least) two not working links, in the row for <code>vendor-options</code> it says</p>
<blockquote>
<p>Enables syntax extensions for XSLT and XPath, specifically the conditional XSLT extensions described here and the XPath otherwise operator</p>
</blockquote>
<p>where</p>
<ol>
<li>"conditional XSLT extensions described here" links to <a href="https://www.saxonica.com/documentation12/index.html#!extensions/xslt-syntax-extensions" class="external">https://www.saxonica.com/documentation12/index.html#!extensions/xslt-syntax-extensions</a> which gives the error "Error in URI hash-path: Section 'xslt-syntax-extensions' not found in path: extensions/xslt-syntax-extensions"</li>
<li>"otherwise" links to <a href="https://www.saxonica.com/documentation12/index.html#!extensions/syntax-extensions/otherwise" class="external">https://www.saxonica.com/documentation12/index.html#!extensions/syntax-extensions/otherwise</a> which gives a similar error "Error in URI hash-path: Section 'syntax-extensions' not found in path: extensions/syntax-extensions/otherwise"</li>
</ol> SaxonJS - Bug #6234 (New): map call with sequence of more than one item as argument doesn't give ...https://saxonica.plan.io/issues/62342023-10-28T21:38:53ZMartin Honnenmartin.honnen@gmx.de
<p>In a test I tried to call an XPath 3.1 map as a function, passing in a sequence of two items as the argument; SaxonJ gives an error but SaxonJS happily runs the code e.g.</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="cp"><?xml version="1.0" encoding="utf-8"?></span>
<span class="nt"><xsl:stylesheet</span> <span class="na">xmlns:xsl=</span><span class="s">"http://www.w3.org/1999/XSL/Transform"</span>
<span class="na">version=</span><span class="s">"3.0"</span>
<span class="na">xmlns:xs=</span><span class="s">"http://www.w3.org/2001/XMLSchema"</span>
<span class="na">exclude-result-prefixes=</span><span class="s">"#all"</span>
<span class="na">expand-text=</span><span class="s">"yes"</span><span class="nt">></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"id-map"</span> <span class="na">select=</span><span class="s">"map { 1 : 2, 2 : (), 3 : 2, 4 : 3 }"</span><span class="nt">/></span>
<span class="nt"><xsl:template</span> <span class="na">match=</span><span class="s">"/"</span> <span class="na">name=</span><span class="s">"xsl:initial-template"</span><span class="nt">></span>
<span class="nt"><test></span>{$id-map((3, 4))}<span class="nt"></test></span>
<span class="nt"><xsl:comment></span>Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}<span class="nt"></xsl:comment></span>
<span class="nt"></xsl:template></span>
<span class="nt"></xsl:stylesheet></span>
</code></pre>
<p>when run with <code>xslt3 -it -xsl:test1.xsl</code> outputs</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span><span class="nt"><test></span>2<span class="nt"></test></span><span class="c"><!--Run with SaxonJS 2.6 Node.js--></span>
</code></pre>
<p>As <a href="https://www.w3.org/TR/xpath-31/#id-maps" class="external">https://www.w3.org/TR/xpath-31/#id-maps</a> defines calling a map as doing <code>map:get</code> with the signature (<a href="https://www.w3.org/TR/xpath-functions-31/#func-map-get" class="external">https://www.w3.org/TR/xpath-functions-31/#func-map-get</a>) <code>map:get($map as map(*), $key as xs:anyAtomicType) as item()*</code> the code should give an error "XPTY0004 A sequence of more than one item is not allowed as the first argument of map".</p>
<p>Interestingly enough, for a direct call <code>map:get($id-map, (3, 4))</code> SaxonJS gives the error "Required cardinality of second argument of map:get() is exactly one; supplied value contains 2 items (xs:integer('3'), xs:integer('4'))".</p> SaxonJS - Bug #6233 (New): ReferenceError: abstractNode is not definedhttps://saxonica.plan.io/issues/62332023-10-26T09:24:04ZThomas Barnekow
<p>I am trying to use SaxonJS 2.6.0 within a Next.js 13 project. I am using code that works on the Node.js runtime in Azure Functions. However, the same code leads to the following exception in Next.js:</p>
<p>⨯ node_modules/.pnpm/saxon-js@2.6.0/node_modules/saxon-js/SaxonJS2N.js (4640:147) @ abstractNode
⨯ ReferenceError: abstractNode is not defined
at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/saxon-js@2.6.0/node_modules/saxon-js/SaxonJS2N.js:277426:14)
at (rsc)/./node_modules/.pnpm/saxon-js@2.6.0/node_modules/saxon-js/SaxonJS2N.js (/Users/thomas/Source/Repos/platforms-starter-kit/.next/server/vendor-chunks/<a href="mailto:saxon-js@2.6.0.js" class="email">saxon-js@2.6.0.js</a>:20:1)
at <strong>webpack_require</strong> (/Users/thomas/Source/Repos/platforms-starter-kit/.next/server/webpack-runtime.js:33:43)
at eval (webpack-internal:///(rsc)/./app/api/render-service-levels/route.ts:5:66)</p> SaxonJS - Bug #6132 (New): documentPool passed to SaxonJS.transform doesn't seem to be used if th...https://saxonica.plan.io/issues/61322023-07-18T16:53:41ZMartin Honnenmartin.honnen@gmx.de
<p>For SaxonJS.transform, I can pass a <code>documentPool</code>, mapping URLs to resources, to allow preloading resources or loading resources from a string.</p>
<p>An example of that is e.g. a stylesheet (shown here as XSLT, for SaxonJS it will be compiled to sef.json)</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="cp"><?xml version="1.0" encoding="utf-8"?></span>
<span class="nt"><xsl:stylesheet</span> <span class="na">xmlns:xsl=</span><span class="s">"http://www.w3.org/1999/XSL/Transform"</span>
<span class="na">version=</span><span class="s">"3.0"</span>
<span class="na">xmlns:xs=</span><span class="s">"http://www.w3.org/2001/XMLSchema"</span>
<span class="na">exclude-result-prefixes=</span><span class="s">"#all"</span>
<span class="na">expand-text=</span><span class="s">"yes"</span><span class="nt">></span>
<span class="nt"><xsl:template</span> <span class="na">name=</span><span class="s">"xsl:initial-template"</span><span class="nt">></span>
<span class="nt"><xsl:sequence</span> <span class="na">select=</span><span class="s">"doc('doc1.xml') => serialize(map{'method':'xml'})"</span><span class="nt">/></span>
<span class="nt"></xsl:template></span>
<span class="nt"></xsl:stylesheet></span>
</code></pre>
<p>and (for Node.js) Javascript code like</p>
<pre><code class="javascript syntaxhl" data-language="javascript"><span class="kd">const</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">path</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">url</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">SaxonJS</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">saxon-js</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">xmlResource1</span> <span class="o">=</span> <span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">getResource</span><span class="p">({</span><span class="dl">'</span><span class="s1">type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">xml</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">text</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1"><root>foo</root></span><span class="dl">'</span> <span class="p">});</span>
<span class="kd">var</span> <span class="nx">doc1Uri</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">doc1.xml</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">docPool</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">xmlResource1</span><span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">doc</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">docPool</span><span class="p">[</span><span class="nx">url</span><span class="p">.</span><span class="nx">pathToFileURL</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="dl">'</span><span class="s1">.</span><span class="dl">'</span><span class="p">,</span> <span class="nx">doc1Uri</span><span class="p">))]</span> <span class="o">=</span> <span class="nx">doc</span><span class="p">;</span> <span class="p">})</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
<span class="c1">//console.log(docPool);</span>
<span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">transform</span><span class="p">({</span> <span class="na">documentPool</span><span class="p">:</span> <span class="nx">docPool</span><span class="p">,</span> <span class="na">stylesheetLocation</span><span class="p">:</span> <span class="dl">'</span><span class="s1">documentPoolTest1.xsl.sef.json</span><span class="dl">'</span> <span class="p">},</span> <span class="dl">'</span><span class="s1">async</span><span class="dl">'</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="nx">result</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">serialize</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">principalResult</span><span class="p">));</span>
<span class="p">});</span>
<span class="p">});</span>
</code></pre>
<p>When I run that with Node I get e.g.</p>
<pre><code><?xml version="1.0" encoding="UTF-8"?>&lt;root&gt;foo&lt;/root&gt;
</code></pre>
<p>so the <code>doc1.xml</code> is resolved from my passed in <code>documentPool</code> property.</p>
<p>However, when I do the same with an XSLT stylesheet having a function exposing <code>xsl:evaluate</code> with a public function and then call that function with <code>SaxonJS.transform</code> to pass in e.g. a string doing <code>doc("doc1.xml")</code> it seems the documentPool is not taken into account and instead I get an error that the file <code>doc1.xml</code> is not found:</p>
<pre><code>Transformation failure: Error FODC0002 at exposeXslEvaluate.xsl#17
Cannot read file file:///C:/Users/marti/OneDrive/Documents/xslt/saxonjs-documentPool/doc1.xml - ENOENT: no such file or directory, open 'C:\Users\marti\OneDrive\Documents\xslt\saxonjs-documentPool\doc1.xml'
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
Error
at new L (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4109:549)
at Object.readFile (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4713:171)
at Object.readFile (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4108:74)
at C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4340:316
at a (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4338:294)
at Object.Ec (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4340:280)
at doc (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4513:298)
at C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4632:444
at Object.I [as evaluate] (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4600:203)
at Object.evaluateXDM (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4933:464)
at C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4630:290
at Object.push (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4390:245)
at e (C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:4987:320)
at C:\Users\marti\AppData\Roaming\npm\node_modules\saxon-js\SaxonJS2N.js:5015:342 {
message: "Cannot read file file:///C:/Users/marti/OneDrive/Documents/xslt/saxonjs-documentPool/doc1.xml - ENOENT: no such file or directory, open 'C:\\Users\\marti\\OneDrive\\Documents\\xslt\\saxonjs-documentPool\\doc1.xml'",
name: 'XError',
code: 'FODC0002',
xsltLineNr: '17',
xsltModule: 'exposeXslEvaluate.xsl'
}
</code></pre>
<p>A sample XSLT is e.g.</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="nt"><xsl:stylesheet</span>
<span class="na">xmlns:xsl=</span><span class="s">"http://www.w3.org/1999/XSL/Transform"</span>
<span class="na">version=</span><span class="s">"3.0"</span>
<span class="na">xmlns:mf=</span><span class="s">"http://example.com/mf"</span>
<span class="na">xmlns:xs=</span><span class="s">"http://www.w3.org/2001/XMLSchema"</span>
<span class="na">exclude-result-prefixes=</span><span class="s">"#all"</span><span class="nt">></span>
<span class="nt"><xsl:function</span> <span class="na">name=</span><span class="s">"mf:eval"</span> <span class="na">as=</span><span class="s">"item()*"</span> <span class="na">visibility=</span><span class="s">"public"</span><span class="nt">></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"expression"</span> <span class="na">as=</span><span class="s">"xs:string"</span><span class="nt">/></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"context-item"</span> <span class="na">as=</span><span class="s">"item()?"</span><span class="nt">/></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"params"</span> <span class="na">as=</span><span class="s">"map(xs:QName, item()*)"</span><span class="nt">/></span>
<span class="nt"><xsl:evaluate</span> <span class="na">xpath=</span><span class="s">"$expression"</span> <span class="na">context-item=</span><span class="s">"$context-item"</span> <span class="na">with-params=</span><span class="s">"$params"</span><span class="nt">/></span>
<span class="nt"></xsl:function></span>
<span class="nt"><xsl:function</span> <span class="na">name=</span><span class="s">"mf:eval"</span> <span class="na">as=</span><span class="s">"item()*"</span> <span class="na">visibility=</span><span class="s">"public"</span><span class="nt">></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"expression"</span> <span class="na">as=</span><span class="s">"xs:string"</span><span class="nt">/></span>
<span class="nt"><xsl:evaluate</span> <span class="na">xpath=</span><span class="s">"$expression"</span> <span class="na">context-item=</span><span class="s">"()"</span> <span class="na">with-params=</span><span class="s">"map{}"</span><span class="nt">/></span>
<span class="nt"></xsl:function></span>
<span class="nt"><xsl:function</span> <span class="na">name=</span><span class="s">"mf:eval"</span> <span class="na">as=</span><span class="s">"item()*"</span> <span class="na">visibility=</span><span class="s">"public"</span><span class="nt">></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"expression"</span> <span class="na">as=</span><span class="s">"xs:string"</span><span class="nt">/></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"context-item"</span> <span class="na">as=</span><span class="s">"item()?"</span><span class="nt">/></span>
<span class="nt"><xsl:evaluate</span> <span class="na">xpath=</span><span class="s">"$expression"</span> <span class="na">context-item=</span><span class="s">"$context-item"</span> <span class="na">with-params=</span><span class="s">"map{}"</span><span class="nt">/></span>
<span class="nt"></xsl:function></span>
<span class="nt"></xsl:stylesheet></span>
</code></pre>
<p>the Javascript code is e.g.</p>
<pre><code class="javascript syntaxhl" data-language="javascript"><span class="kd">const</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">path</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">url</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">SaxonJS</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">saxon-js</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">xmlResource1</span> <span class="o">=</span> <span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">getResource</span><span class="p">({</span><span class="dl">'</span><span class="s1">type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">xml</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">text</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1"><root>foo</root></span><span class="dl">'</span> <span class="p">});</span>
<span class="kd">var</span> <span class="nx">doc1Uri</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">doc1.xml</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">docPool</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">xmlResource1</span><span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">doc</span> <span class="o">=></span> <span class="p">{</span> <span class="nx">docPool</span><span class="p">[</span><span class="nx">url</span><span class="p">.</span><span class="nx">pathToFileURL</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="dl">'</span><span class="s1">.</span><span class="dl">'</span><span class="p">,</span> <span class="nx">doc1Uri</span><span class="p">))]</span> <span class="o">=</span> <span class="nx">doc</span><span class="p">;</span> <span class="p">})</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">docPool</span><span class="p">);</span>
<span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">transform</span><span class="p">({</span>
<span class="na">documentPool</span><span class="p">:</span> <span class="nx">docPool</span><span class="p">,</span>
<span class="na">stylesheetLocation</span><span class="p">:</span> <span class="dl">'</span><span class="s1">exposeXslEvaluate.xsl.sef.json</span><span class="dl">'</span><span class="p">,</span>
<span class="na">stylesheetBaseURI</span><span class="p">:</span> <span class="nx">url</span><span class="p">.</span><span class="nx">pathToFileURL</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="dl">'</span><span class="s1">.</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">exposeXslEvaluate.xsl</span><span class="dl">'</span><span class="p">)),</span>
<span class="na">initialFunction</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Q{http://example.com/mf}eval</span><span class="dl">'</span><span class="p">,</span>
<span class="na">functionParams</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">doc("doc1.xml")</span><span class="dl">'</span><span class="p">],</span>
<span class="na">destination</span><span class="p">:</span> <span class="dl">'</span><span class="s1">raw</span><span class="dl">'</span>
<span class="p">},</span> <span class="dl">'</span><span class="s1">async</span><span class="dl">'</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="nx">result</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">serialize</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">principalResult</span><span class="p">));</span>
<span class="p">});</span>
<span class="p">});</span>
</code></pre> SaxonJS - Bug #6069 (AwaitingInfo): "Unexpected XSLT error" "Cannot add item to tree: (object)"https://saxonica.plan.io/issues/60692023-06-09T05:31:07ZConal Tuohy
<p>I've encountered a strange error running a compiled stylesheet under SaxonJS 2.5 in NodeJS v18.16.0. The stylesheet is compiled on the same platform with the <code>xslt3</code> utility.</p>
<p>This all used to work at some point in the past and I'm not sure what has changed, but I have managed to cut the stylesheet down to a fairly minimal example that reproduces the problem.</p>
<p>My JS code invokes the stylesheet using <code>SaxonJS.transform</code>, and passes parameters to it using <code>stylesheetParams</code>. One of the parameters (<code>$source-uri</code>) is an absolute <code>file:</code> which the stylesheet passes to the <code>doc</code> function, and then applies templates to the result.</p>
<p>The stylesheet implements a pipeline of several transformations by applying templates to a document, capturing the result as a variable, then applying templates to the variable, capturing the result as another variable, applying templates to that, etc. Without that pipeline the stylesheet works OK (i.e. if in the stylesheet below I replace <code><xsl:copy-of select="$phase-1"/></code> with <code><xsl:copy-of select="$source"/></code>, then I get the result I expect; a copy of the source document).</p>
<pre><code class="xml syntaxhl" data-language="xml"><span class="nt"><xsl:transform</span> <span class="na">version=</span><span class="s">"3.0"</span> <span class="na">xmlns:xsl=</span><span class="s">"http://www.w3.org/1999/XSL/Transform"</span><span class="nt">></span>
<span class="c"><!--
Test of weird SaxonJS regression
--></span>
<span class="nt"><xsl:param</span> <span class="na">name=</span><span class="s">"source-uri"</span><span class="nt">/></span>
<span class="nt"><xsl:template</span> <span class="na">name=</span><span class="s">"xsl:initial-template"</span><span class="nt">></span>
<span class="c"><!-- read the document --></span>
<span class="nt"><xsl:variable</span> <span class="na">name=</span><span class="s">"source"</span> <span class="na">select=</span><span class="s">"doc($source-uri)"</span><span class="nt">/></span>
<span class="c"><!-- transform the document with an identity mode --></span>
<span class="nt"><xsl:variable</span> <span class="na">name=</span><span class="s">"phase-1"</span><span class="nt">></span>
<span class="nt"><xsl:apply-templates</span> <span class="na">mode=</span><span class="s">"identity"</span> <span class="na">select=</span><span class="s">"$source"</span><span class="nt">/></span>
<span class="nt"></xsl:variable></span>
<span class="c"><!-- write the document --></span>
<span class="nt"><xsl:result-document</span> <span class="na">href=</span><span class="s">"/tmp/regression-test-output.xml"</span> <span class="na">method=</span><span class="s">"xml"</span> <span class="na">indent=</span><span class="s">"no"</span><span class="nt">></span>
<span class="nt"><xsl:copy-of</span> <span class="na">select=</span><span class="s">"$phase-1"</span><span class="nt">/></span>
<span class="nt"></xsl:result-document></span>
<span class="nt"></xsl:template></span>
<span class="nt"><xsl:mode</span> <span class="na">name=</span><span class="s">"identity"</span> <span class="na">on-no-match=</span><span class="s">"shallow-copy"</span><span class="nt">/></span>
<span class="nt"></xsl:transform></span>
</code></pre>
<p>Here's the JS API call I use to invoke the stylesheet (my minimal example uses only the <code>source-uri</code> parameter, but the real stylesheet needs those other two):</p>
<pre><code class="javascript syntaxhl" data-language="javascript"><span class="kd">const</span> <span class="nx">transformationResults</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">SaxonJS</span><span class="p">.</span><span class="nx">transform</span><span class="p">(</span>
<span class="p">{</span>
<span class="na">stylesheetFileName</span><span class="p">:</span> <span class="dl">"</span><span class="s2">/srv/tasks/src/xslt/document-function-regression-test.xsl.sef.json</span><span class="dl">"</span><span class="p">,</span>
<span class="c1">//stylesheetFileName: "/srv/tasks/src/xslt/process-tei-to-page-files.xsl.sef.json",</span>
<span class="na">stylesheetParams</span><span class="p">:</span> <span class="p">{</span>
<span class="na">identifier</span><span class="p">:</span> <span class="nx">identifier</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">source-uri</span><span class="dl">"</span><span class="p">:</span> <span class="nx">sourceURI</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">page-identifier-regex</span><span class="dl">"</span><span class="p">:</span> <span class="nx">configuration</span><span class="p">.</span><span class="nx">ui</span><span class="p">.</span><span class="nx">filename</span><span class="p">.</span><span class="nx">checkNameStructure</span><span class="p">,</span>
<span class="p">},</span>
<span class="na">baseOutputURI</span><span class="p">:</span> <span class="nx">output</span> <span class="p">?</span> <span class="nx">output</span> <span class="p">:</span> <span class="nx">sourceURI</span><span class="p">,</span> <span class="c1">// output into the same folder as the source data file</span>
<span class="p">},</span>
<span class="dl">"</span><span class="s2">async</span><span class="dl">"</span>
<span class="p">);</span>
</code></pre>
<p>Logging the error thrown by SaxonJS.transform produces:</p>
<pre><code> console.error
L {
message: 'An unexpected error occurred in XSLT code. Please report the following information: \n' +
'Error SXJS0004 in document-function-regression-test.xsl line 11:\n' +
'Internal error: Cannot add item to tree (object) <TEI xmlns="http://www.tei-c.org/ns/1.0">\n' +
' <teiHeader>\n' +
' <fileDesc>\n' +
' <titleStmt>\n' +
' <title/>\n' +
' <author/>\n' +
' </titleStmt>\n' +
' <editionStmt>\n' +
' <edition>\n' +
' <date>2022-04-04</date>\n' +
' </edition>\n' +
' </editionStmt>\n' +
' <publicationStmt>\n' +
' <p>unknown</p>\n' +
' </publicationStmt>\n' +
' <sourceDesc>\n' +
' <p>Converted from a Word document</p>\n' +
' </sourceDesc>\n' +
' </fileDesc>\n' +
' <encodingDesc>\n' +
' <appInfo>\n' +
' <application xml:id="docxtotei" ident="TEI_fromDOCX" version="2.15.0">\n' +
' <label>DOCX to TEI</label>\n' +
' </application>\n' +
' </appInfo>\n' +
' </encodingDesc>\n' +
' <revisionDesc>\n' +
' <listChange>\n' +
' <change>\n' +
' <date>2022-04-13T04:31:35Z</date>\n' +
' <name/>\n' +
' </change>\n' +
' </listChange>\n' +
' </revisionDesc>\n' +
' </teiHeader>\n' +
' <text>\n' +
' <body>\n' +
' <p rend="Normal" style="text-align: left; ">\n' +
' <hi rend="Page">msword_example-001</hi> Text of page 1</p>\n' +
' <p rend="Normal" style="text-align: left; ">\n' +
' <pb/>\n' +
' </p>\n' +
' <p rend="Normal" style="text-align: left; ">\n' +
' <hi rend="Page">msword_example-002</hi> Text of page 2 starts here</p>\n' +
' <p rend="Normal" style="text-align: left; ">More page 2 text.<pb/>\n' +
' </p>\n' +
' <p rend="Normal" style="text-align: left; ">\n' +
' <hi rend="Page">msword_example-003</hi> Finally this we have this, the transcription of page 3; the third page of the document, i.e. the page which follows immediately after the second page, also known as “page 2”.</p>\n' +
' <p rend="Normal" style="text-align: left; ">This is more of the third page.<pb/>\n' +
' </p>\n' +
' <p rend="Normal" style="text-align: left; ">\n' +
' <hi rend="Page">msword_example_2-001</hi> This is the first page of transcript of a different item; an item called msword_example_2; this page should not be extracted from the file.</p>\n' +
' </body>\n' +
' </text>\n' +
'</TEI>',
stack: 'Error: \n' +
' at new L (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4109:549)\n' +
' at Object.a [as ga] (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4110:349)\n' +
' at a.append (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4372:52)\n' +
' at Object.q [as gh] (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4362:243)\n' +
' at SC (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4971:310)\n' +
' at e.hf (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4976:85)\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4973:289\n' +
' at wc.Object.<anonymous>.ca.forEachItem (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4206:583)\n' +
' at e.Bb (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4973:256)\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4376:8\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4358:33\n' +
' at Array.forEach (<anonymous>)\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4358:6\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4379:17\n' +
' at Object.push (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4390:143)\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4600:290\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4386:258\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4386:309\n' +
' at Object.push (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4390:143)\n' +
' at e (/srv/tasks/node_modules/saxon-js/SaxonJS2N.js:4988:69)\n' +
' at /srv/tasks/node_modules/saxon-js/SaxonJS2N.js:5015:342',
name: 'UnexpectedXSLTError',
code: 'SXJS0004',
xsltLineNr: '11',
xsltModule: 'document-function-regression-test.xsl'
}
</code></pre>
<p>The TEI XML content in that error message is indeed the content of the file identified by the <code>$source-uri</code> parameter.</p>
<p>The stylesheet succeeds when launched from the command line:</p>
<pre><code>node /srv/tasks/node_modules/xslt3 -it -t -xsl:/srv/tasks/src/xslt/document-function-regression-test.xsl source-uri=file:///srv/tasks/src/test-data/Succeeds-word_doc_upload/fake-msword-example/msword_example-tei.xml
SaxonJS 2.5 from Saxonica
Node.js version v18.16.0
Compiling stylesheet /srv/tasks/src/xslt/document-function-regression-test.xsl
Stylesheet compilation time: 0.284s
Initial template: Q{http://www.w3.org/1999/XSL/Transform}initial-template
Asynchronous transform with options: stylesheetText={"N":"package","version":"30",(string), stylesheetBaseURI=file:///srv/tasks/src/xslt/doc(string), stylesheetParams=[object Object](string), outputProperties=[object Object](string), extraOptions=[object Object](string), destination=stdout(string), baseOutputURI=file:///srv/tasks/(string), logLevel=2(string), initialTemplate=Q{http://www.w3.org/1999/XSL/T(string),
SEF generated by SaxonJS 2.5 at 2023-06-09T05:22:48.208Z
Promising to write to file:///tmp/regression-test-output.xml
<?xml version="1.0" encoding="UTF-8"?>
Execution time: 0.147s
Memory used: 29.21Mb
Transformation complete
</code></pre>
<p>The output file <code>ile:///tmp/regression-test-output.xml</code> is there and is a copy of the input file <code>file:///srv/tasks/src/test-data/Succeeds-word_doc_upload/fake-msword-example/msword_example-tei.xml</code></p>
<p>Naturally I can also run the stylesheet successfully under SaxonJ.</p> SaxonJS - Bug #5916 (New): Using xsl:merge with xsl:merge-source for-each-source="'input1.xml'" s...https://saxonica.plan.io/issues/59162023-03-12T12:40:08ZMartin Honnenmartin.honnen@gmx.de
<p>I have tried to run an XSLT 3 example using XSLT 3's new xsl:merge through SaxonJS 2.5's <code>xslt3</code> command line tool under Windows 11 with Node 16, a simple example using e.g.</p>
<pre><code class="xml syntaxhl" data-language="xml"> <span class="nt"><xsl:template</span> <span class="na">name=</span><span class="s">"xsl:initial-template"</span><span class="nt">></span>
<span class="nt"><list></span>
<span class="nt"><xsl:merge></span>
<span class="nt"><xsl:merge-source</span> <span class="na">name=</span><span class="s">"master"</span> <span class="na">for-each-source=</span><span class="s">"'input1.xml'"</span> <span class="na">sort-before-merge=</span><span class="s">"yes"</span> <span class="na">select=</span><span class="s">"/list/item"</span><span class="nt">></span>
<span class="nt"><xsl:merge-key</span> <span class="na">select=</span><span class="s">"@id"</span> <span class="na">order=</span><span class="s">"ascending"</span><span class="nt">/></span>
<span class="nt"></xsl:merge-source></span>
</code></pre>
<p>gives an error</p>
<pre><code>Transformation failure: Error XPDY0002 at sheet1.xsl#7
Focus for / is absent
Error XPDY0002 at sheet1.xsl#7
Focus for / is absent
</code></pre>
<p>The code runs fine through Saxon HE 11.5 Java.</p>
<p>Full files attached; command line <code>xslt3 -t -it -xsl:sheet1.xsl</code> gives output</p>
<pre><code>SaxonJS 2.5 from Saxonica
Node.js version v16.17.1
Compiling stylesheet C:\Users\marti\OneDrive\Documents\xslt\blog-xslt-3-by-example\nested-merge\sheet1.xsl
Stylesheet compilation time: 0.342s
Initial template: Q{http://www.w3.org/1999/XSL/Transform}initial-template
Asynchronous transform with options: stylesheetText={"N":"package","version":"30",(string), stylesheetBaseURI=file://C:/Users/marti/OneDrive(string), stylesheetParams=[object Object](string), outputProperties=[object Object](string), extraOptions=[object Object](string), destination=stdout(string), baseOutputURI=file://C:/Users/marti/OneDrive(string), logLevel=2(string), initialTemplate=Q{http://www.w3.org/1999/XSL/T(string),
SEF generated by SaxonJS 2.5 at 2023-03-12T13:32:13.485+01:00
Transformation failure: Error XPDY0002 at sheet1.xsl#7
Focus for / is absent
Error XPDY0002 at sheet1.xsl#7
Focus for / is absent
</code></pre> SaxonJS - Bug #5830 (New): Stylesheets with entity references do not compilehttps://saxonica.plan.io/issues/58302023-01-18T04:33:31ZEvan Lenzevan@lenzconsulting.com
<p>See the attached test.xsl file. When I try to compile it using the latest release:</p>
<pre><code>xslt3 -xsl:test.xsl -export:test.sef.json
</code></pre>
<p>I get the following output:</p>
<pre><code>Error FODC0002:
Failed parsing XML in file://path/to/test.xsl: Reference to unknown entity &REUSABLE_PATTERN; at line 8 column 41
Failed to compile stylesheet
</code></pre>
<p>I did notice feature <a class="issue tracker-2 status-1 priority-2 priority-default" title="Feature: Recognize entity declarations in DTDs (New)" href="https://saxonica.plan.io/issues/4597">#4597</a> ("Recognize entity declarations in DTDs"). However, I believe this should be considered a bug report rather than a feature request, as I believe a conforming XML processor will <em>always</em> be able to recognize entity declarations in the internal DTD subset. This is actually the first time I've ever seen them not recognized in an XML processing context.</p>
<p>I sometimes use them for repeated long XSLT patterns. My temporary workaround is to expand them all (repeating them throughout the stylesheet).</p> SaxonJS - Bug #5807 (New): current() does not work when invoked via xsl:evaluatehttps://saxonica.plan.io/issues/58072023-01-11T17:50:01ZJohn Dziurlaj
<p>When passing the following expression to <code>@xpath</code> of <code>xsl:evaluate</code> in SaxonJS, <code>instance('i2')/month[@code = current()]</code> , I get the error "The current() construct is not implemented in SaxonJS"</p>
<ul>
<li>Stylesheet location (context): <a href="https://github.com/Saxonica/Saxon-Forms/blob/5ab05598219361cfb56b730da9d30409b0726cf1/src/saxon-xforms.xsl#L1468-L1481" class="external">https://github.com/Saxonica/Saxon-Forms/blob/5ab05598219361cfb56b730da9d30409b0726cf1/src/saxon-xforms.xsl#L1468-L1481</a>
</li>
<li>See also: <a href="https://github.com/Saxonica/Saxon-Forms/issues/20" class="external">https://github.com/Saxonica/Saxon-Forms/issues/20</a>
</li>
<li>Normative reference: <a href="https://www.w3.org/TR/xforms11/#fn-current" class="external">https://www.w3.org/TR/xforms11/#fn-current</a>
</li>
</ul>
<p>Note that this error is masked by another error related to namespace declarations, which is more fully described in Saxon-Forms <a class="issue tracker-1 status-3 priority-2 priority-default closed" title="Bug: position variable incorrectly removed in ForClause (Closed)" href="https://saxonica.plan.io/issues/20">#20</a>. (the error can be suppressed by removing the <code>@namespace-context</code> from <code>xsl:evaluate</code>).</p> W3C QT Specifications - Bug #4359 (New): Incorrect note regarding fn:collation-key()https://saxonica.plan.io/issues/43592019-10-24T08:57:58ZMichael Kaymike@saxonica.com
<p>In F&O 3.1, the notes for fn:collation-key() say:</p>
<blockquote>
<p>*This specification does not mandate that collation keys should retain ordering. This is partly because the primary use case is for maps, where only equality comparisons are required, and partly to allow the use of binary data types (which are currently unordered types) for the result. The specification may be revised in a future release to specify that ordering is preserved. *</p>
</blockquote>
<p>This paragraph is incorrect and should be deleted. The spec does now mandate that fn:collation-key() is order-preserving, and binary data types are now ordered, which was done specifically to make this possible.</p> W3C QT Specifications - Bug #4236 (New): Note regarding streamability of fn:filterhttps://saxonica.plan.io/issues/42362019-06-14T15:16:53ZMichael Kaymike@saxonica.com
<p>Section §19.8.9.10 discusses streamability of the fn:for-each function but the Note contains a reference to fn:filter, making it unclear whether this is a typo for fn:for-each. There's no separate section for streamability of fn:filter, which might be useful, even if the default rules say it all already.</p> W3C QT Specifications - Bug #4222 (New): [xslt30] Visibility of xsl:paramhttps://saxonica.plan.io/issues/42222019-05-16T23:00:16ZMichael Kaymike@saxonica.com
<p>The XSLT 3,0 spec makes confusingly inconsistent statements about the visibility of global parameters.</p>
<ul>
<li>
<p>The grammar for <code>xsl:param</code> does not allow a <code>visibility</code> attribute</p>
</li>
<li>
<p>In §3.5.3.1, under <code>xsl:expose</code>, we say "The visibility of a variable declared using an <code>xsl:param</code> element is always public."</p>
</li>
<li>
<p>§9.6 (Static parameters) says: "When the static attribute [of <code>xsl:param</code>] is present with the value yes, the visibility attribute must not have a value other than <code>private</code>." But in fact, no visibility attribute is allowed by the grammar. It is clear in this section that the intent is for static parameters to always be private: there is a note explaining why (specifically, so they cannot be overridden, which is necessary to allow separate compilation of packages; however, I don't see why visibility="final" can't be allowed, which would achieve the same aim.</p>
</li>
</ul>
<p>I think one aspect of this that the spec fails to address is: when package P "uses" package Q, it is presumably using a version of Q whose static parameters have been bound to particular values. But there is no way for P to say what these values should be. There can be two compiled instances of Q with different values bound to the static parameters, and the effect of using these two instances is likely to be quite different.</p>