带有Saxon的Apache Camel Xpath 2.0不能在RouteBuilder/谓词中使用 [英] Apache Camel Xpath 2.0 with Saxon does not look to work in RouteBuilder / Predicates

查看:117
本文介绍了带有Saxon的Apache Camel Xpath 2.0不能在RouteBuilder/谓词中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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-saxonApache 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆