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

Resolve includes/imports

Open seanmcilvenna opened this issue 10 years ago • 3 comments

If my xslt/xml files are stored in a DB, is it possible to customize the include/import resolution of XSLT files so that I can pass the XSLT's requested includes from the database.

Pseudo example:

xslt.resolver = function(fileName) { var buffer; // read file content into buffer from DB return buffer; }

seanmcilvenna avatar Jul 30 '15 05:07 seanmcilvenna

I think libxslt has some mechanisms for these kind of things. But I suspect it would be quite complicated and honestly I have no plan to look into it soon.

Of course as usual, a pull request would be very welcome.

albanm avatar Nov 19 '15 19:11 albanm

you can load your xslt file as a xml document, xpath into it to find your special includes and do in-place replacement. guess you know that, and i agree it would be nice to be automatic but its complicated for sure

neu-rah avatar Nov 20 '15 09:11 neu-rah

There are two possible hooks which could be used for this: xsltDocLoaderFunc (implemented in xsltDocDefaultLoaderFunc) or the one set by xmlSetExternalEntityLoader (with default implementation xmlDefaultExternalEntityLoader). The former is in libxslt and has to return a parsed document, while the latter is in libxml and has to return a pointer to an xmlParserInput structure. The default file access seems to go through xmlNewInputFromFile which doesn't seem to provide a hook.

Note that the function pointer variables used for both the hooks described above aren't thread-local, so we can't set it per stylesheet, but would have to set it for the whole process. We could of course replace it with a small function which examines some thread-local varibale and delegates to the default implementation (which is static but which can be read from the xsltDocDefaultLoader variable resp. retrieved using xmlGetExternalEntityLoader) if no thread-local override was found. See occurrences of tls in libxmljs.cc for an example of thread-local storage.

If we hook in with the xmlParserInput structure, should we be gluing that to a Buffer, or would it be more appropriate to follow the node stream API? Or perhaps both, at least in the long run? Buffers are certainly easier since we don't need to block and wait for another thread in the xmlInputReadCallback implementation.

gagern avatar Nov 20 '15 11:11 gagern