Project

Profile

Help

Bug #6132

open

documentPool passed to SaxonJS.transform doesn't seem to be used if the stylesheet uses fn:transform or xsl:evaluate

Added by Martin Honnen over 1 year ago. Updated over 1 year ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
API
Sprint/Milestone:
Start date:
2023-07-18
Due date:
% Done:

0%

Estimated time:
Applies to JS Branch:
2
Fix Committed on JS Branch:
Fixed in JS Release:
SEF Generated with:
Platforms:
Company:
-
Contact person:
-
Additional contact persons:
-

Description

For SaxonJS.transform, I can pass a documentPool, mapping URLs to resources, to allow preloading resources or loading resources from a string.

An example of that is e.g. a stylesheet (shown here as XSLT, for SaxonJS it will be compiled to sef.json)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:template name="xsl:initial-template">
    <xsl:sequence select="doc('doc1.xml') => serialize(map{'method':'xml'})"/>
  </xsl:template>

</xsl:stylesheet>

and (for Node.js) Javascript code like

const path = require('path');

const url = require('url');


const SaxonJS = require('saxon-js');

var xmlResource1 = SaxonJS.getResource({'type': 'xml', 'text' : '<root>foo</root>'  });

var doc1Uri = 'doc1.xml';

var docPool = {};

xmlResource1.then(doc => { docPool[url.pathToFileURL(path.resolve('.', doc1Uri))] = doc; })
.then(() => {
  //console.log(docPool);
  SaxonJS.transform({ documentPool: docPool, stylesheetLocation: 'documentPoolTest1.xsl.sef.json' }, 'async').then(result => {
    console.log(SaxonJS.serialize(result.principalResult));
  });
});

When I run that with Node I get e.g.

<?xml version="1.0" encoding="UTF-8"?>&lt;root&gt;foo&lt;/root&gt;

so the doc1.xml is resolved from my passed in documentPool property.

However, when I do the same with an XSLT stylesheet having a function exposing xsl:evaluate with a public function and then call that function with SaxonJS.transform to pass in e.g. a string doing doc("doc1.xml") it seems the documentPool is not taken into account and instead I get an error that the file doc1.xml is not found:

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'
}

A sample XSLT is e.g.

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:mf="http://example.com/mf"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">

  <xsl:function name="mf:eval" as="item()*" visibility="public">
    <xsl:param name="expression" as="xs:string"/>
    <xsl:param name="context-item" as="item()?"/>
    <xsl:param name="params" as="map(xs:QName, item()*)"/>
    <xsl:evaluate xpath="$expression" context-item="$context-item" with-params="$params"/>
  </xsl:function>

  <xsl:function name="mf:eval" as="item()*" visibility="public">
    <xsl:param name="expression" as="xs:string"/>
    <xsl:evaluate xpath="$expression" context-item="()" with-params="map{}"/>
  </xsl:function>

  <xsl:function name="mf:eval" as="item()*" visibility="public">
    <xsl:param name="expression" as="xs:string"/>
    <xsl:param name="context-item" as="item()?"/>
    <xsl:evaluate xpath="$expression" context-item="$context-item" with-params="map{}"/>
  </xsl:function>

</xsl:stylesheet>

the Javascript code is e.g.

const path = require('path');

const url = require('url');


const SaxonJS = require('saxon-js');

var xmlResource1 = SaxonJS.getResource({'type': 'xml', 'text' : '<root>foo</root>'  });

var doc1Uri = 'doc1.xml';

var docPool = {};

xmlResource1.then(doc => { docPool[url.pathToFileURL(path.resolve('.', doc1Uri))] = doc; })
.then(() => {
  console.log(docPool);
  SaxonJS.transform({
      documentPool: docPool,
      stylesheetLocation: 'exposeXslEvaluate.xsl.sef.json',
      stylesheetBaseURI: url.pathToFileURL(path.resolve('.', 'exposeXslEvaluate.xsl')),
      initialFunction: 'Q{http://example.com/mf}eval',
      functionParams: ['doc("doc1.xml")'],
      destination: 'raw'
    }, 'async').then(result => {
    console.log(SaxonJS.serialize(result.principalResult));
  });
});

Files

documentPoolTest1.xsl (394 Bytes) documentPoolTest1.xsl Martin Honnen, 2023-07-18 18:51
documentPoolTest1.xsl.sef.json (976 Bytes) documentPoolTest1.xsl.sef.json Martin Honnen, 2023-07-18 18:51
exposeXslEvaluate.xsl (1.04 KB) exposeXslEvaluate.xsl Martin Honnen, 2023-07-18 18:51
exposeXslEvaluate.xsl.sef.json (3.98 KB) exposeXslEvaluate.xsl.sef.json Martin Honnen, 2023-07-18 18:51
testDocumentPool1.js (587 Bytes) testDocumentPool1.js direct use of documentPool with SaxonJS.transform works Martin Honnen, 2023-07-18 18:51
testDocumentPoolWithXslEvaluate1.js (816 Bytes) testDocumentPoolWithXslEvaluate1.js test case passes in documentPool to SaxonJS.transform but fails to resolve file for exposeXslEvaluate.xsl and some XPath expression accessing the document Martin Honnen, 2023-07-18 18:51

Please register to edit this issue

Also available in: Atom PDF Tracking page