如何将 Saxon 设置为 Java 中的 Xslt 处理器?

2022-09-01 06:33:46

这是一个简单的问题,但我找不到答案。我有一个XSLT 2.0样式表,我正在尝试用Java处理。它依赖于来自Saxon的XSL元素。

我当前的类在简单的 XSLT 1.0 下工作正常,但是使用 Saxon 构建的 2.0 XSLT 时,我遇到了有关无法识别的元素的错误。

我不知道如何告诉Java使用Saxon作为处理器。我在课堂上使用javax.xml.transform。这是我可以设置的属性吗?我应将其设置为什么?谢谢!

编辑我想出了如何将属性设置为使用Saxon,但现在我得到了这个错误。

Provider net.sf.saxon.TransformerFactoryImpl not found

我如何在我的申请中包括撒克逊人?


答案 1

有多种方法可以执行此操作(按查找优先级的顺序):

直接实例化

显式实例化 Saxon 工厂(对 Michael 上面的评论表示赞同):

TransformerFactory fact = new net.sf.saxon.TransformerFactoryImpl()

这种方法意味着您的代码在编译时被锁定为使用 Saxon。这可以被视为优势(没有使用错误处理器运行的风险)或劣势(没有机会在执行时配置不同的处理器 - 甚至没有Saxon Enterprise Edition)。

对于 Saxon-PE,请替换 。对于 Saxon-EE,请替换 。com.saxonica.config.ProfessionalTransformerFactorycom.saxonica.config.EnterpriseTransformerFactory

指定类名

在构造工厂类时指定它:

TransformerFactory fact = TransformerFactory.newInstance(
        "net.sf.saxon.TransformerFactoryImpl", null);

注意:从 Java 6 开始可用Java 5 版本没有此方法。

此方法允许您在执行时选择处理器,同时仍避免类路径搜索的成本和风险。例如,您的应用程序可以提供一些配置机制,通过在各种 Saxon 工厂类之间进行选择,允许它与不同的 Saxon 版本一起运行。

使用系统属性

在创建实例之前设置系统属性:javax.xml.transform.TransformerFactory

System.setProperty("javax.xml.transform.TransformerFactory",    
        "net.sf.saxon.TransformerFactoryImpl");

或者在命令行上(为便于阅读而换行):

java -Djavax.xml.transform.TransformerFactory=
        net.sf.saxon.TransformerFactoryImpl YourApp

此方法的缺点是系统属性会影响整个 Java VM。将此属性设置为选择 Saxon 可能意味着应用程序中的某些其他模块(您可能甚至不知道)开始使用 Saxon 而不是 Xalan,并且如果该模块使用特定于 Xalan 的 XSLT 构造,则该模块可能会因此而失败。

使用属性文件

创建以下文件:

JRE/lib/jaxp.properties

具有以下内容:

javax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl

此方法具有与使用系统属性类似的后果。

服务加载程序

在类路径上的任何 JAR 中创建以下文件:

META-INF/services/javax.xml.transform.TransformerFactory

具有以下内容:

net.sf.saxon.TransformerFactoryImpl

此方法的缺点是,对类路径的微小更改可能会导致应用程序使用不同的 XSLT 引擎运行,而该引擎可能从未使用过应用程序进行测试。

平台默认值

如果上述操作均未完成,则将加载平台默认实例。可以在此处找到此可插拔层的友好描述。TransformerFactory

请注意,这里的“平台”是指 Java VM,而不是运行它的硬件或操作系统。对于所有当前已知的 Java VM,平台默认值是 Xalan 的一个版本(仅支持 XSLT 1.0)。不能保证将来每个 Java VM 都始终如此。

我认为这个答案是反对Java做事方式的论据。


答案 2

您可以显式构造必需的对象 和 对象,以确保它们是 Saxon 实现,而不是默认实现。SourceResult


推荐