首页 > 解决方案 > Saxon 交付 V1 Xpath 对象

问题描述

我已经成功使用 SAXON HE 9.5.1-5 一段时间了。我们正在对我们平台上的某些版本的组件进行一般升级,其中包括迁移到 Saxon 9.8.0-8 使用该版本的代码失败。以下是我们的 Spring beans 文件:

    <bean id="xpathFactory" class="net.sf.saxon.xpath.XPathFactoryImpl" factory-method="newInstance"/>
    <bean id="xpath" factory-bean="xpathFactory" factory-method="newXPath"/>
    <bean id="myRequestValidator" class="gov.dhs.ice.prime.query.RequestValidator">
            <constructor-arg index="0" ref="xpath"/>

如您所见,最后一个 bean 传递了“newXPath”方法的结果。对于调试,我得到传入对象的名称。使用 9.5.1-5 时,传入对象是 net.sf.saxon.xpath.XPathEvaluator 对象现在使用 9.8.0-8,我收到 org.apache.xpath.jaxp.XPathImpl 对象

RequestValidator 程序然后作为构造函数的一部分进行一些 XPath 编译。使用 XPathEvaluator 对象,一切都很好(一直以来都是如此) 现在我得到了一个 org.apache.xpath.jaxp.XPathImpl 对象,当程序尝试编译 V2 XPath 语句时,构造函数会失败。V1 工作正常。
那么,为什么这个新版本返回的对象与以前不同呢?

我确实尝试直接构建 net.sf.saxon.xpath.XPathEvaluator ..

    <bean id="xpath" class="net.sf.saxon.xpath.XPathEvaluator"/>
    <bean id="myRequestValidator" class="gov.dhs.ice.prime.query.RequestValidator">
            <constructor-arg index="0" ref="xpath"/>

这适用于新版本。但是,似乎文档推荐了早期的方法。

有什么想法吗?谢谢

标签: javasaxon

解决方案


某些版本的 Saxon 不再将自己注册为 JAXP XPathFactory,请参阅http://saxonica.com/html/documentation9.8/xpath-api/jaxp-xpath/factory.html

JAXP API 的设计基础是,当您的应用程序调用 XPathFactory.newInstance() 时,通过检查系统属性的值并搜索类路径来选择 XPath 引擎。如果您依赖这种机制,那么您的应用程序最终可能会使用从未测试过的 XPath 引擎运行。由于不同的 XPath 引擎在许多重要方面可能不同(最明显的是它们支持的 XPath 版本),这很容易导致应用程序失败。因此,Saxon 不再将自己(在 JAR 文件清单中)标识为 JAXP XPath 供应商。如果你想加载 Saxon 作为你的 XPath 引擎,你需要明确地选择它;仅仅把它放在类路径上是不够的

newInstance您认为您正在调用的net.sf.saxon.xpath.XPathFactoryImpl方法实际上是抽象基类的方法https://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--那就是调用假设的基类的另一个重载https://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance-java.lang.String-加载 JAXP 注册的 XPathFactory。

所以你应该做的是:“如果你想使用 Saxon 作为你的 XPath 实现,你必须直接实例化 net.sf.saxon.xpath.XPathFactoryImpl 类。”,例如在 Java 代码new net.sf.saxon.xpath.XPathFactoryImpl()中。

我不确定它是如何以这种 bean 语法声明方式表达的,但也许您知道这一点,或者其他人可以提供帮助。


推荐阅读