将 Xalan 与 Saxon 一起使用

Posted

技术标签:

【中文标题】将 Xalan 与 Saxon 一起使用【英文标题】:Using Xalan alongside Saxon 【发布时间】:2012-06-28 19:19:03 【问题描述】:

我在我的应用程序中使用 Xalan,但需要使用 Saxon 和参考实现来生成测试输出以进行比较。我想在单元测试期间同时使用它们。 但是,一旦我在项目 .pom 中添加对 Saxon 的依赖项,应用程序似乎在测试期间将 Saxon 用于所有 xslt 和 XPath 操作:

<dependency>
  <groupId>net.sf.saxon</groupId>
  <artifactId>Saxon-HE</artifactId>
  <version>9.4</version>
  <scope>test</scope>
</dependency>

这会使主应用程序在生成输出时由于不同的 XPath 行为而失败。在测试范围之外运行主应用程序时,它可以工作。

如何在测试期间使用 Xalan 运行主应用程序,但使用 Saxon 运行测试?

我尝试在运行 Xalan 和 Saxon 部件之前设置以下属性:

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

我还尝试将 Xalan 和 Saxon 部分放在不同的项目中,我还尝试在第三个项目中同时使用它们,结果相同。

【问题讨论】:

【参考方案1】:

这里是完整性的解决方案:

System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":"
    + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
    "org.apache.xpath.jaxp.XPathFactoryImpl");
System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":"
    + NamespaceConstant.OBJECT_MODEL_SAXON,
    "net.sf.saxon.xpath.XPathFactoryImpl");

XPathFactory jaxpFactory =
    XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI);
XPathFactory saxonFactory =
    XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);

【讨论】:

【参考方案2】:

避免依赖 JAXP 工厂机制来选择转换引擎。而是明确加载您想要的引擎:它更可靠,速度更快。对于撒克逊人,将调用替换为

TransformerFactory.newInstance()

new net.sf.saxon.TransformerFactoryImpl()

供 Xalan 使用

new org.apache.xalan.processor.TransformerFactoryImpl()

【讨论】:

它是失败的 XPath 部分。有没有办法告诉 XPathFactory 使用默认实现?这个答案说明了如何做相反的事情,使用撒克逊实现***.com/questions/926222/…。 根据jarvana.com/jarvana/view/xalan/xalan/2.7.0/xalan-2.7.0.jar!/org/…,这将是 org.apache.xpath.jaxp.XPathFactoryImpl。无论如何,我建议对您的应用程序使用 JAXP 机制,而不是使其依赖于实现,除非您的应用程序中有极端用例。仅在测试中使用 impl 依赖代码。 我不同意。很多人因为他们使用 JAXP 机制并在他们的应用程序需要 XPath 1.0 处理器时选择 XPath 2.0 处理器而失败。您不能明确要求 XPath 1.0 处理器;如果你不说你想要什么,你就不知道你会得到什么,而且它可能行不通。 我不得不使用 Saxon,因为参考实现依赖于它。根据您的回答,我得到了它,谢谢! (请参阅下面我的答案中的解决方案) 对答案的更新:它对 XSLT 仍然有效,但对于 XPath,Saxon 不再将自己声明为 JAXP XPath 工厂提供者。那是因为用于 XPath 的 JAXP API 定义太松散(许多参数声明为“对象”,其中实现定义了实际接受的内容)以至于为一个 XPath 处理器编写的应用程序很少与不同的处理器一起工作,尤其是当它实现了不同版本的 XPath 语言。

以上是关于将 Xalan 与 Saxon 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

无法让 ICU4J 与 Saxon HE 10.3 一起使用

在 Saxon/C 中使用条件包含/静态参数?

Xalan 2.7 中缺少字符串函数,改用 java.lang.String 吗?

在 python 中使用撒克逊语

是否可以在 Android 上从 Xalan 调用 Java 扩展函数?

Xalan XSLT - 内存堆空间不足