Hi Christian,
I'm not a Java programmer, but Eric Burke: "Java and XSLT" (O'reilly, 2001) has a chapter on stylesheet compilation and caching using JAXP, with actual code: see section 5.4.2. "A Stylesheet Cache". (I found the text online. Not sure about the legal status, so I won't post links here, but you can easily find that section if you want.)
Here is another article on caching with JAXP, with code samples: http://www.javaworld.com/article/2073394/java-xml/transparently-cache-xsl-tr...
If you don't mind me referring to another open-source product, eXist-db seems to cache XSLT stylesheets. (In any case they have a caching-flag in the transformer section of their config file.)
As far as I can tell, eXist uses JAXP (or javax.xml.transform.*), so this might be similar to BaseX' implementation?
Their code has a CachedStylesheet class: https://github.com/eXist-db/exist/blob/develop/src/org/exist/xquery/function...
On the other hand, Burke's book and the article mentioned above date back quite a while and JAXP may no longer be the best way to handle transformations, not for Saxon anyway: http://www.saxonica.com/html/documentation/using%2Dxsl/embedding
Saxon has a new API (s9api) that is a better fit for XSLT 2.0 and higher: http://www.saxonica.com/html/documentation/using-xsl/embedding/s9api-transfo...
The page outlines how you create an XsltCompiler and "call the compile() method to compile a stylesheet. The result is an XsltExecutable, which can be used as often as you like, in the same thread or in different threads."
In the ASP.NET/Saxon project that I would like to migrate, we cache this XsltExecutable object.
Web requests get the XsltExecutable from cache (or create and cache it on a cache miss), and call the Load() method to create an XsltTransformer that executes the transformation.
When the XSLT stylesheets are modified on disk, the cache is cleared, so we can edit them on the fly.
I suppose there are various ways to do this automatically. Tracking individual stylesheet files is not trivial, since they may import other files.
Our stylesheets have a lot of import inheritance, so we simply watch the entire stylesheet folder and clear the cache on any change. The next request will take a second or so to compile whatever stylesheets are needed, but that's OK.
If it is hard to come up with a generic cache clearing strategy, a custom XQuery function that clears the cache would be good enough (for a manual reset after editing).
While looking at the BaseX code and trying to transpose my .NET background to Java, I briefly toyed with the idea of trying to implement a custom XQuery function myself, but I had to give up pretty soon.
One of the things that puzzles me is where to cache the XsltExecutables. Is there some sort of global context where these objects could be stored?
(ASP.NET provides an Application object with caching facilities that lives above Sessions and is available to the entire web application. Is there something similar in Java, accessible from RESTXQ in BaseX?
Not sure, but this subject may touch on the Static context thread that came up a few days ago on the list?)
So, in short, would one of these options be feasible:
1. basic XSLT caching with the existing JAXP interface, as described in the articles or similar; 2. specific saxon:transform() etc. functions that use the new Saxon interface (and do caching); 3. idem but implemented for the regular xslt:transform(), or maybe the function in XQFO 3.1 (thanks for the link, I was not aware of this)?
Thinking forward, absolutely wonderful would be some form of tight integration with Saxon that passes nodes from BaseX to Saxon directly, without serializing/parsing.
Incidentally, there is an interesting note on this topic on the eXist developer platform (scroll to the bottom): https://github.com/eXist-db/exist/issues/791
But any of option 1-3 (or similar) would do the trick and be great!
Best regards, Tom
On 5/02/2017 15:01, Christian GrĂ¼n wrote:
Hi Tom,
You are right. xslt:transform() does nothing else than sending stylesheets to the registered XSLT processor (which is usually Xalan or Saxon).
The XQFO 3.1 spec [1] will provide an fn:transform function that provides a "cache" option. As the definition of this function is very Saxon-specific, I am not sure if we will completely support it in future. For now, if you know how caching is enabled in Saxon, feel free to provide me with some example code, and I will see if I can easily embed it in our current architecture.
Cheers, Christian
[1] https://www.w3.org/TR/xpath-functions-31/#func-transform
On Sun, Feb 5, 2017 at 1:52 AM, Tom De Herdt tom.deherdt@skynet.be wrote:
Hi all,
I'm evaluating BaseX as an alternative (and very attractive) platform for an XML/XSLT-based website that needs to be migrated from ASP.NET.
The website relies heavily on XSLT. Each page is generated on-the-fly with Saxon.NET, using a complex set of stylesheets. To get reasonable performance, stylesheets are compiled on first use and cached for subsequent requests.
This is crucial, as XSLT compilation is typically orders of magnitude slower than execution; without caching, the server would spend most of the time compiling the same stylesheets over and over again.
I was happy to find that BaseX can use Saxon, but as far as I can see, xslt:transform() does not cache compiled stylesheets. Can anyone confirm this?
If not, are there any plans to support stylesheet caching in the future?
Or is there a way to reuse compiled stylesheets manually?
Thanks, Tom De Herdt