node-libxslt icon indicating copy to clipboard operation
node-libxslt copied to clipboard

Support extension functions written in JavaScript

Open gagern opened this issue 10 years ago • 10 comments

It would be nice if we could extend the XSLT resp. XPath language using Extensions functions. LibXSLT provides custom extensions. It would be great to have that API wrapped on the JavaScript side, so one can write extension functions there.

gagern avatar Dec 02 '14 17:12 gagern

Nice ! I will have a look, but I don't have much time for this so I can't make any promise.

Of course a pull request is welcome.

albanm avatar Dec 02 '14 19:12 albanm

Sorry, but things are not looking very good on this topic.

I have done a few tests saved in this commit: https://github.com/albanm/node-libxslt/commit/29f1ad65bf749326783636c985c19115a857e058

But I am not convinced that it will bring a satisfactory solution.

albanm avatar Dec 16 '14 20:12 albanm

please! i think this is the last obstacle on my port... please add EXSLT

neu-rah avatar Jan 13 '15 11:01 neu-rah

please add EXSLT

EXSLT is a fixed set of extension functions, and I believe that libxslt supports most of these already. What I'm talking about here is the option to add arbitrary extension functions written in JS.

I have done a few tests saved in this commit: 29f1ad6

Funny, you started at a completely different point than where I'd have started. The fact that there are a large number of drive-by fixes in that commit makes reading it difficult, though.

My first steps were trying to get type conversions implemented. Which is easy enough for simple types, but gets really complicated if you are dealing with nodes. For that one would need to wrap large parts of the libXML API for use from node. As I recall, node-libxslt ships its own version of libXML so it would have to do that as well to provide consistency. Perhaps it would be better to build on some existing libXML wrapper for Node instead? Linking against that might be tricky, but that approach would ensure consistent versions.

But I guess that even if we don't get all types supported yet, this would still be useful for several applications. Having some part of the functionality is better than none at all, imo.

  • How to use functors as extension function for libxslt ?

You don't. The return type of any extension function has to be converted to an XPath data type. So anything which is not boolean, numeric, node or node list (no guarantee that this list is exhaustive) should probably be turned into a string via a simple toString call.

I know XSLT in Java allows passing arbitrary Java objects between extension functions. It might be possible to do the same here as well. But if at all I'd consider this for a later improvement, not for the initial implementation of extension functions.

  • How to refer to a v8 function from async queue worker?
  • Impossible to use an async function as extension function. So no db access, etc.

Async processing is something I hadn't considered at all. I guess the only clean way would be to run the XSLT processor in a separate thread, and to block that thread while the main node thread processes some callback. Once that yields a result, the result could be returned to XSLT. Something like this JS-like pseudocode, but actually written in C:

function callbackWrapper(args) {
  create mutex m and lock it.
  var res;
  function doCallback() {
    res = callback(args);
    unlock m;
  }
  enqueue doCallback on main event queue.
  wait for m to become unlocked.
  return res.
}

If the callback throws an exception, that might make things even more difficult. In an ideal world, any exception raised by the callback would cause the XSLT process to abort and would get passed to the error event handler of the XSLT event dispatcher. I'm not sure whether libxslt is properly reentrant. If not, then we'd have to make sure that we don't start more than one XSLT process at the same time. But that's a general issue, not specific to extension functions, right?

gagern avatar Jan 13 '15 13:01 gagern

@neu-rah EXSLT is now supported in version 0.3.0. Actually all required libraries were already included, extension functions were simply not registered. Anyway this is fixed and published.

@gagern I need a little more time to refresh my memories and write down an answer. But I will come back !

albanm avatar Jan 13 '15 20:01 albanm

ok, built in module functions are working (at least I've tested with evaluate, Ok). looking forward for user functions great work, thanks!

neu-rah avatar Jan 14 '15 07:01 neu-rah

Here is my current work in progress. It's already usable to some degree: I can pass values of type boolean, number and string in both directions, and I can call the custom function in synchroneous and in asynchroneous context. Supporting other types, nodes and node sets in particular, will probably require more work since these need to be properly wrapped. But as a starting point I'm quite happy with this here.

gagern avatar Jan 30 '15 22:01 gagern

Hello.I'm trying to use regular expressions in my xslt.Is there any way to achieve this?Thanks!

tasoss avatar May 23 '16 14:05 tasoss

@tasoss: node-libxslt supports exslt, which supports regular expressions. Should not be a problem, but it's qzite distinct from what this issue here is about.

gagern avatar May 23 '16 19:05 gagern

Thanks for answering...Sorry for posting here.I will try to post on a forum/mailing list or something because i need more help on reg. expressions.Thanks again!

tasoss avatar May 23 '16 20:05 tasoss