带有Saxon的Apache Camel Xpath 2.0不能在RouteBuilder/谓词中使用 [英] Apache Camel Xpath 2.0 with Saxon does not look to work in RouteBuilder / Predicates
问题描述
我正在使用ServiceCix 4.5.3(包括Camel 2.10.7),并且能够使用如下选项端点通过Saxon库进行XSLT 2.0转换:
I am using ServiceMix 4.5.3 which includes Camel 2.10.7 and I am able to make XSLT 2.0 transformations with the Saxon library using the option endpoint like this:
...
to("xslt:stylesheet.xsl?transformerFactoryClass=net.sf.saxon.TransformerFactoryImpl")
...
但是,当我尝试使用xpath函数时:
However when I try to use the xpath function like this:
private Namespaces ourNS = new Namespaces("myns",
"urn:com:company:domain:namespace:myns/1");
// ... some code ...
// Make a predicate to filter according a header :
// The code attribute looks like: urn:phone:apple:iphone:4s
Predicate isNotSamePhoneBrand = PredicateBuilder.isNotEqualTo(
xpath("tokenize(/myns:Phone/@code, ':')[3]").namespaces(ourNS),
header("PhoneBrand"));
如果我执行上面的代码,它说tokenize()函数是未知的.我猜是因为它仍然使用xalan(xpath 1.0)代替了Saxon.
If I execute the above code it says the tokenize() function is unknown. I guess it is because it still uses xalan (xpath 1.0) instead Saxon.
我也尝试像在骆驼文档中一样附加.saxon().
I also tried as well to append the .saxon() as in the Camel documentation
Predicate isNotSamePhoneBrand = PredicateBuilder.isNotEqualTo(
xpath("tokenize(/myns:Phone/@code, ':')[3]").namespaces(ourNS).saxon(),
header("PhoneBrand"));
但是他找不到Saxon实现工厂会犯一个错误:
But it makes an error that he cannot find the Saxon implementation factory:
Caused by: javax.xml.xpath.XPathFactoryConfigurationException: No XPathFctory implementation found for the object model: http://saxon.sf.net/jaxp/xpath/om
在OSGI上下文中,我验证了camel-saxon
和Apache ServiceMix :: Bundles :: saxon9he (9.3.0.11_2)
均已部署.
In my OSGI context I verified that both camel-saxon
and Apache ServiceMix :: Bundles :: saxon9he (9.3.0.11_2)
are deployed.
我们计划很快升级到ServiceMix 5,但我不知道此问题是否仍然存在,对于我来说,版本4.5.3的解决方案会更好.
We are planning to upgrade to ServiceMix 5 soon but I do not know if this problem is still there or not, a solution for the version 4.5.3 would be better for me.
推荐答案
最后,我找到了骆驼路线的可行解决方案:
Finally I found a working solution for the camel route:
由于.saxon()对我的路线没有影响,所以我决定换一种方式,我发现有一个特定的选项可以像这样覆盖Xpath工厂:
As the .saxon() was without effect on my route, I decided to look another way and I found there is a specific option to override the Xpath factory like this:
.factory(new net.sf.saxon.xpath.XPathFactoryImpl())
此后,我不得不使用.resultType(String.class)
强制将Xpath的结果转换为String.
After that I had to force the conversion of the result of the Xpath into a String with .resultType(String.class)
.
完整的谓词看起来像这样:
The full predicate will looks like this:
Predicate isNotSamePhoneBrand = PredicateBuilder.isNotEqualTo(
xpath("tokenize(/myns:Phone/@code, ':')[3]").namespaces(ourNS)
.factory(new net.sf.saxon.xpath.XPathFactoryImpl()).resultType(String.class),
header("PhoneBrand"));
,现在可以很好地识别标记化功能(xpath 2.0).
and now the tokenize function (xpath 2.0) is very well recognized.
我发现,在像这样的骆驼处理器中使用工厂实现的实例化时,我必须做同样的事情:
I found that I have to do the same thing with the instantiation of the factory implementation when I use it in a camel Processor like this:
net.sf.saxon.xpath.XPathFactoryImpl factory = new net.sf.saxon.xpath.XPathFactoryImpl();
XPath xpath = factory.newXPath();
NodeList channels = (NodeList) xpath.evaluate(
"//*:Channels/*:Channel/text()",
body, XPathConstants.NODESET);
这不是动态的,但是我想在所有地方都强制使用Saxon,然后此解决方案才能满足我们的需求.
This is not dynamic but I want to force the usage of Saxon everywhere then this solution fit our needs.
这篇关于带有Saxon的Apache Camel Xpath 2.0不能在RouteBuilder/谓词中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!