Saxon doesn't support `saxon:output` anymore - xslt

I'm trying to use Saxon 9.1.0.8 HE to apply (recent) Docbook XSL, and getting this:
Don't know how to chunk with SAXON 9.1.0.8 from Saxonica
Processing terminated by xsl:message at line 46 in chunker.xsl
Docbook XSL source claims that:
<!-- This stylesheet works with XSLT implementations that support -->
<!-- exsl:document, saxon:output, or Xalan's redirect:write -->
<!-- Note: Only Saxon 6.4.2 or later is supported. -->
...and a visit to line 46 mentioned in the error message (which tests for element-available('saxon:output')), and to Saxon documentation, shows that the root of the problem is that Saxon no longer recognizes the saxon:output extension.
This source suggests that to make Saxon 9.4 compatible with XSLT 1.0 (which is what the stylesheets are in, and what saxon:output used to be good for in the first place), some kind of "backward compatible behavior" must be enabled. But why, and how?
(The docbook stylesheet in question does specify <xsl:stylesheet version="1.0" xmlns:saxon="http://icl.com/saxon">.)

I'm no expert in DocBook, but I believe the Docbook 1.0 stylesheets probably work best with Saxon 6.5.5, and if you want to use the latest Saxon releases (e.g. for performance) then you're probably better off using the Docbook 2.0 stylesheets: see
http://norman.walsh.name/2011/08/25/docbook-xslt-2

If you want to run XSLT 1.0 stylesheets trying to access extensions in the namespace xmlns:saxon="http://icl.com/saxon" then you should use the lastest version of Saxon 6 which is 6.5.5 I think.
Saxon 9 is an XSLT 2.0 processor and I don't think that comment talking about "Saxon 6.4.2 or later" has Saxon 9 in mind, it is solely talking about the Saxon 6.x releases of the XSLT 1.0 processor.
Other than that I agree with Ken, if you want to use Saxon 9 then edit the stylesheets to use the XSLT 2.0 xsl:result-document.

Saxon 9 supports XSLT 2.0, so just use <xsl:result-document> to create multiple result trees.

Related

schematron validation using XSLT 2.0 file on net core (net 5)

I have 3 XML files which contains some rules that an XML document has to be fit in that rules.
I have converted these rule sets using oxygen xml editor to XSLT 2.0 file (some rules has XSLT function) and I need to work this XSLT 2.0 file on net core to validate an XML document against that rule set.
As I understand net core or net 5 don't support XSLT 2.0 and some library like Saxon does not support net core +.
So is there any workaround to validate XML document using XSLT file ?
How can convert to rule set to XSLT 1.0 file so net core can handle validation process. ?
Or is there any other way to do the job?
SaxonCS for .NET Core 5 has been released recently and allows you to run XSLT 2 or XSLT 3 based Schematron implementations like Schxslt with .NET Core 5 or 6.
SaxonCS is available on NuGet https://www.nuget.org/packages/SaxonCS or from Saxonica https://www.saxonica.com/download/dotnet.xml under a commercial package.

The meaning of the version attribute in the xsl:stylesheet tag

In a reply to a post I made the other day Dimitre pointed out, correctly of course, that I had given an XSLT 2 answer to an XSLT 1 question.
However, he also upbraided me for posting an answer that hadn't been tested. I had in fact tested it and even though the version attribute was set to "1.0" and I used an XSLT 2 replace function every worked with errors or warnings.
So this raised a question - what does the version attribute mean if it doesn't restrict the language to a particular version?
I did try reading the w3 spec but my eyes started to bleed.
FWIW: I use Oxygen and Saxon 9.3 EE
Firstly, the XSLT specification says how an XSLT processor interprets the version attribute, but it doesn't constrain what pieces of software other than an XSLT processor do with it. For example, an IDE (such as XML Spy) might look at the version attribute and use it to decide whether to launch an XSLT 1.0 or XSLT 2.0 processor. Once an XSLT 1.0 or 2.0 processor is launched, its behaviour is controlled by the relevant spec.
What an XSLT 1.0 processor does with the version attribute is defined by the XSLT 1.0 specification; what a 2.0 processor does is defined by the XSLT 2.0 spec.
The XSLT 1.0 spec says that if the version is NOT 1.0, the processor runs in forwards compatibility mode. This basically means that it does its best to ignore constructs that aren't defined in the 1.0 spec. So if your stylesheet says version="2.0", and you run it with a 1.0 processor, then an attribute that is new in 2.0 like xsl:sort/#collation will be ignored. An instruction that isn't recognized causes a failure only if it is actually executed, and if it has no xsl:fallback child instruction to give a fallback behaviour for 1.0 processors. The design principle is that using 2.0 constructs should not cause a 1.0 processor to fail; wherever possible, it should cause it to run with some kind of fallback behaviour.
The XSLT 2.0 specification (which controls the behaviour of a 2.0 processor) distinguishes verion<2.0, version=2.0, and version>2.0. When version<2.0, the processor runs in "backwards compatible mode". This doesn't mean that 2.0 constructs are rejected; rather it means that 1.0 constructs are executed with semantics as close as possible to those defined in the 1.0 specification. For example, all arithmetic is carried out as double floating point, even if the operands are decimals. When version>2.0, the processor runs in forwards compatible mode, which is very like forwards compatible mode in the 1.0 specification: it means that if you use XSLT 3.0 constructs, the processor will do its best to ignore them or execute fallback instructions.
I also use oXygen for both XSLT 1.0 and 2.0 development. If I try to use an XSLT 2.0 function in a stylesheet that has a version number of 1.0, oXygen will warn me.
Check your oXygen settings and make sure you're validating XSLT 1.0 with a 1.0 processor:
Notice I'm validating 1.0 with Xalan.
Also, I always test my 1.0 answers with a 1.0 processor; usually with both Saxon 6.5.5 and Xalan.

How to use XML wrapped in CDATA inside another XML for XSL transformation?

An XML document contains another XML element, which is wrapped in CDATA.
How can the wrapped XML be used for XSL and XSL-FO transformation (version 1)?
If you are willing to take multiple transformation steps then it is possible. Output the relevant section with disable-output-escaping to turn the escaped XML into valid XML. Process it in a subsequent step.
It does require the escaped XML to be well-formed. And some parsers require the intermediate result to be serialized (to disk or else) first to make sure the escaped XML is properly unescaped before it enters the subsequent transformations.
This is not possible with standard XSLT 1.0 or 2.0, in a single transformation.
It can be done using Saxon 9 Professional Edition or Enterprise Edition. These products have a saxon:parse() extension function. Or use the XPath 3.0 parse-xml() function, which is also supported by recent versions of Saxon PE/EE.
As #grtjn points out, it is possible to do it with a two-pass process. Stylesheet 1 turns the CDATA-wrapped text into parseable XML (using <xsl:value-of select="whatever" disable-output-escaping="yes"/>). Stylesheet 2 then processes the serialized result produced by stylesheet 1.

error when calling exslt in Saxon

I get the error message:
"Cannot find a matching 1-argument function named
{http://exslt.org/common}node-set()"
when running a xslt transformation with the Saxon engine.
I've tried using Saxon PE and EE on Windows XP and it gives the same error. EXSLT should work out of the box with Saxon. Does anyone have a solution on how I may resolve this, please?
Saxon PE and EE are XSLT 2.0 processor implementations where you don't need a node-set extension function as in XSLT 2.0 the difference between result tree fragments and node-sets does no longer exists. So you should be able to simply use e.g. $var/foo/bar instead of exsl:node-set($var)/foo/bar in your stylesheets where you process variables.

Replacement of <xsl:eval> and <xsl:script> in XSL

I am trying to modify an xsl which is of the older version. I come across the following:
<xsl:eval>FormatAccount(this)</xsl:eval>
<xsl:script>
function FormatAccount(e) {
// function details
}
</xsl:script>
I am trying to call the FormatAccount() javascript function using <xsl:eval> and the function is written in <xsl:script>.
How to do this as per the latest standards?
The latest standard is XSLT 2.0 http://www.w3.org/TR/xslt20/, it does not have any facility to define functions in Javascript, it however allows you to define functions with XSLT itself: http://www.w3.org/TR/xslt20/#stylesheet-functions.
XSLT 2.0 is supported by XSLT 2.0 processors like Saxon 9 http://saxon.sourceforge.net/, AltovaXML Tools http://www.altova.com/altovaxml.html or XQSharp http://www.xqsharp.com/xqsharp/beta.htm.
If you want to use Javascript to define extension functions we need to know which XSLT processor you use, of those three XSLT 2.0 processors I mentioned I think only AltovaXML Tools allows that (http://manual.altova.com/AltovaXML/altovaxmlcommunity/index.html?xextmsxsl.htm), and only, I think, to allow easier migration of XSLT 1.0 stylesheets written for Microsoft MSXML.
If you want to use an XSLT 1.0 processor then there too defining extension functions in a particular programming language like Javascript depends on the processor you use, for MSXML there is an msxsl:script element: http://msdn.microsoft.com/en-us/library/ms256042.aspx.
Embedded extension functions in other language is not the content model of XSLT.
Extension elements and extension functions are part of the content model as described in http://www.w3.org/TR/xslt#extension : it's implementation dependant how exactly an XSLT processor register those extensions.
As pointed by #Martin Honnen's answer, in XSLT 2.0 you can declare "stylesheet functions" with XSLT itself.