如何获取有关 XSLT 处理器运行的 XSL 版本的信息

How to get info about which XSL version XSLT Processor runs

如何获取有关哪个 XSL 版本 XSLT 处理器 运行 的信息?

我正在评估撒克逊家庭版 (HE10-SJ)。由于这个包似乎同时带有 XSL2.0 和 XSL3.0,我想知道如何获取有关 XSLT 处理器将使用哪个 XSL 的信息 运行。我完全知道在 XSL 文件中设置 XSL 版本,但即使我将 XSL 中的 XSL 版本添加到 5(显然不存在),它仍然会 运行 并处理。

我也明白,如果我在 XSL 样式表中添加专用于 XSL2.0/XSL3.0 的代码,并将 XSL 样式表设置为 XSL1.0,我很可能会收到错误或XSLT 不会处理该请求。

我添加了标志“-t”以获取一些信息,但只能看到 java 版本,而不是 XSLT/XSL 版本。结果提取在这里:

Saxon-HE 10.5J from Saxonica
Java version 11.0.10
Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser

Saxon 9.8 及更高版本是 XSLT 3 处理器,当然您可以 运行 XSLT 2 代码甚至 XSLT 1.0 代码,向后兼容模式下的 XSLT 1.0 https://www.w3.org/TR/xslt-30/#backwards.

您可以检查 system-property('xsl:version') XSLT 版本,如果支持向后兼容模式,还可以检查 属性 xsl:supports-backwards-compatibility;它在 Saxon 10、9.9 和更高版本的 9.8 版本中。我认为只有最早的 9.8 HE 版本试图禁用该模式。

“XSLT 处理器”通常符合“XSLT 规范”的一个特定版本。一个特定的软件产品可能包括用于规范的多个版本的 XSLT 处理器,但最好将它们视为不同的处理器,即使它们共享代码。

给定一个 XSLT 处理器和一个样式表,处理器会查看 @version 属性,这会影响它的行为方式。

如果@version="1.0",则 XSLT 2.0 或 3.0 处理器将以“向后兼容模式”评估某些结构,这更接近于 XSLT 1.0 处理器处理它们的方式。但它仍然是 XSLT 2.0 或 3.0 处理器,遵循 2.0 或 3.0 规范的规则,如果样式表使用需要 2.0 或 3.0 的构造,这些构造仍然有效。

如果版本=“5.0”,比如说,处理器将在“向前兼容模式”下工作,这基本上意味着它会忽略它不理解的结构。向前兼容模式的初衷主要是为了在 web 上部署,以便更容易编写 运行 与任何浏览器支持的样式表,无论它支持哪个 XSLT 版本。它在实现这个目标方面并不是很成功,(a) 因为浏览器从未超过 1.0,并且 (b) 因为简单地忽略新构造通常会给您带来无法使用的结果。这种概念对于像 CSS 这样的语言比对于 XSLT 更有意义。

这里有一些代码似乎可以解决问题,但肯定还有更简单的方法吗?

import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

public final class StringSource extends StreamSource {

    final String string;

    private StringSource(final String string) {
        this.string = string;
    }
    @Override
    public Reader getReader() {
        return new StringReader(string);
    }

    private static final String STYLESHEET = ""
            + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">"
            +     "<xsl:output method=\"xml\" omit-xml-declaration=\"yes\" />"
            +     "<xsl:template match=\"/\"><xsl:value-of select=\"system-property('xsl:version')\"/></xsl:template>"
            + "</xsl:stylesheet>";

    public static void main(final String[] args) throws Exception {

        final Templates    templates   = TransformerFactory.newInstance().newTemplates(new StringSource(STYLESHEET));

        final StringWriter writer      = new StringWriter();

        final Transformer  transformer = templates.newTransformer();
        ;                  transformer.transform(new StringSource("<AnyOldXml/>"), new StreamResult(writer));

        System.out.println("Max. Supported XSLT Version.: " + writer);
    }
}