Node.JS: Evaluation context and asynchronous processing other than HTTP requests
Added by Gustavo Oga about 4 years ago
Calling Asynchronous functions (Promises) from global object¶
I have node.js asynchronous code that I would like to call from an XSLT template.
The documentation talks about calling global functions here: https://www.saxonica.com/saxon-js/documentation/index.html#!development/global.
function square(x) { return String(x*x) }
... <xsl:value-of select="js:square('5')" />...
... the function that I want to call would follow the same pattern, except that it returns a Promise:
function square(x) { return new Promise((resolve) => { ... async work and resolve(result); } }
... <xsl:value-of select="js:square('5')" />...
It was pointed to me ixsl:schedule-action can be used to perform async work, but as far as I can tell it only supports HTTP requests.
Is there any other way to perform a call to an async function from a XSL?
Using an object other than the global or window object as JavaScript context¶
[I've split your second question into a separate thread. See https://saxonica.plan.io/boards/5/topics/8084 - MHK]
Replies (3)
Please register to reply
RE: Node.JS: Evaluation context and asynchronous processing other than HTTP requests - Added by Michael Kay about 4 years ago
We don't have this capability at the moment, I'm afraid. It's on our roadmap: see my Balisage 2020 paper for an outline of our thinking on this:
https://www.balisage.net/Proceedings/vol25/html/Kay01/BalisageVol25-Kay01.html
It's a fairly major project so it's going to take a little while.
(I wonder if there's something you can improvise using events in the meantime?)
RE: Node.JS: Evaluation context and asynchronous processing other than HTTP requests - Added by Gustavo Oga about 4 years ago
Sadly it seems ixsl:event is only available on the browser side:
https://www.saxonica.com/saxon-js/documentation/index.html#!ixsl-extension/functions/event
Node.js does have event emitter support, so I'm guessing this could be made available at some point:
https://nodejs.org/api/events.html
For now, it seems I won't be able to call my async code unless I put it through an HTTP request, which is doable albeit a bit wasteful for my purposes.
RE: Node.JS: Evaluation context and asynchronous processing other than HTTP requests - Added by Gustavo Oga about 4 years ago
I decided to go ahead and implement the asynchronous action through an HTTP request, despite the additional overhead involved.
My XSL looks like this:
My source doc is something like:
<topic xmlns:fq="https://eoga.dev/fishq#" xmlns:fx="https://eoga.dev/fishx#" xmlns="https://eoga.dev/fishx#">
<fq:person name="Emmanuel" />
</topic>
The relevant part of the XSL:
<xsl:template match="fq:*">
<query-result>
<xsl:variable name="query-name" select="xs:string(local-name())" />
<xsl:variable name="query-params" select="map:merge(@* ! map{local-name(): string()})" />
<xsl:variable name="query-uri" select="'https://localhost/_query_/' || $query-name" />
<ixsl:schedule-action document="{$query-uri}">
<xsl:call-template name="render-query">
<xsl:with-param name="query-name" select="$query-uri"/>
</xsl:call-template>
</ixsl:schedule-action>
</query-result>
</xsl:template>
<xsl:template name="render-query">
<xsl:param name="query-name"/>
<xsl:apply-templates select="doc($query-name)"/>
{$query-name}
<ok>DONE.</ok>
</xsl:template>
The output:
<topic xmlns:fq="https://eoga.dev/fishq#" xmlns:fx="https://eoga.dev/fishx#" xmlns="https://eoga.dev/fishx#">
<query-result />
</topic>
I can see that Saxon/JS is performing the request. If I introduce an error on the https://localhost/_query_/person, it even throws an exception because of malformed XML. So it is picking up the document. But when it calls the template, nothing happens: not only doc() doesn't have the document yet, but also the rest of the template seems to be ignored. It looks as if the call-template directive is not doing anything.
Please register to reply