使用 apache camel 转换器 EIP 将模块导入 xquery

2022-01-19 00:00:00 java apache-camel

我有一个非常简单的骆驼路线,除了使用的 xquery,这就是我将其提取到单独文件中的原因.在我的骆驼路线中,我使用 Transformer EIP 调用 xquery:

I have a camel route which is pretty simple, except for the used xquery which is why I extracted it into a separate file. In my camel route I call the xquery with the Transformer EIP:

.transform().xquery("resource:classpath:xquery/myCoolXQuery.xquery",String.class)

XQuery 本身工作正常,但由于一些功能更改,我现在想导入另一个 XQuery 模块,我想将其用作具有一些帮助功能的库",因为我有很多 XQuery 文件可以使用它们.

The XQuery itself works fine, but because of some functional changes I now want to import another XQuery module which I want to use as a "library" with some helping functions, because I have lots of XQuery-Files which could use them.

所以我在 XQuery 中所做的是:

So what I did in my XQuery is:

xquery version "3.0" encoding "UTF-8";

declare namespace fn = 'http://www.w3.org/2005/xpath-functions';

(: Library of really helpful functions :)
import module namespace lib = "http://handofnod.com/xquery-lib" at "classpath:xquery/lib.xquery";

问题:

如何配置 Apache Camel,使 StandardModuleURIResolver 能够从 classpath 加载导入的模块?

Question:

How can I configure Apache Camel that the StandardModuleURIResolver is able to load the imported module from the classpath?

不幸的是,apache camel 现在在 StandardModuleURIResolver 中抛出 NullpointerException:

Unfortunately apache camel now throws a NullpointerException in the StandardModuleURIResolver at:

if ("classpath".equals(absoluteURI.getScheme())) {
    String path = absoluteURI.getPath();
    is = this.config.getDynamicLoader().getResourceAsStream(path);

那是因为absoluteURI(即"classpath:xquery/lib.xquery")不能正确转换,变量pathNULL(这几乎是代码的味道,但现在不是我的事).

That's because the absoluteURI (which is "classpath:xquery/lib.xquery") cannot be converted correctly and the variable path is NULL (that's pretty much code smell but not my business now).

absoluteURI 无法转换,因为 net.sf.saxon.query.XQueryParserthis.env.getStaticBaseURI()<中没有设置值/代码>.

The absoluteURI cannot be converted because the net.sf.saxon.query.XQueryParser has no value set in the this.env.getStaticBaseURI().

所以我在调试期间尝试将 staticBaseURI 值设置为 classpath 但随后 StandardModuleURIResolver 也返回一个 absoluteURIgetPath() 中有一个 NULL 值,从而导致相同的 NullPointerException.

So I tried during debugging to set the staticBaseURI value to classpath but then the StandardModuleURIResolver also returns an absoluteURI which has a NULL value in the getPath() thus resulting in the same NullPointerException.

所以现在我不知道如何将 Transformer-EIP 与 XQuery 一起使用,XQuery 使用 module import 来实现一些帮助函数.

So now I don't have any clue how to use the Transformer-EIP with an XQuery which uses a module import for some helper functions.

另一个可能的解决方案是不使用在 Apache Camel 中实现的 Transformer-EIP,而是使用 ToDefinition 因为可以定义自定义 Saxon Configuration一个 URL 参数,它可以使用覆盖的 ModuleURIResolver ,然后就没有问题了.

Another possible solution would be to not use the Transformer-EIP implemented in Apache Camel but instead use the ToDefinition because there it is possible to define a custom Saxon Configuration over an URL parameter which can use an overwritten ModuleURIResolver which then hasn't the problem.

另外,我当然可以使用自定义 Processor 实现来实现我想要的,但这不是使用提供 EIP 实现的 Camel 的重点.

Also, sure I could use a custom Processor implementation to achieve what I want, but that's not the point in using Camel which provides implementation for EIPs.

如果我可以在我的 XQuery 中使用带有模块导入的 Transformer-EIP,那就太好了.

It would be great if I could use the Transformer-EIP with module import in my XQuery.

  • Spring-Boot 2.1.0.RELEASE
  • Apache Camel 2.22.2
  • 使用 Maven 构建

谁能帮帮我?

我从 Camel 和 Saxon 下载了源代码,以便能够在更了解发生了什么的情况下进行调试,并尝试了一些事情:

I downloaded the sources from Camel and Saxon to be able to debug with more understanding what happens and tried some things:

首先我尝试使用绝对路径:

First I tried to use an absolute path:

.transform().xquery("resource:classpath:/xquery/myCoolXQuery.xquery",String.class)

这样我不再得到 NullPointerException 因为在 getQuerySourceStandardModuleURIResolver 路径不是 NULL 不再:

This way I don't get the NullPointerException anymore because in the StandardModuleURIResolver at getQuerySource the path is not NULL anymore:

不幸的是,该文件无法加载config.getDynamicLoader().getResourceAsStream(path); 并返回 NULL.

Unfortunately the file cannot be loaded by config.getDynamicLoader().getResourceAsStream(path); and returns NULL.

所以我认为我将 xquery 文件从 srcmainesoures 下的目录中直接移动,但这也没有帮助,我得到了相同的结果.

So I thought I move the xquery files from the directory directly under srcmainesoures but that also didn't help and I had the same result.

推荐答案

由于我的问题似乎没有答案,所以我进一步调试,似乎无法以任何方式使用 XQuery 配置 Transformer-EIP.此外,我无法找到从类路径加载导入的 xquery 模块的任何方法,因此我更改了代码,现在我通过提供自定义配置支持的 XQueryEndpoint 调用我的 xquery:

Since it seems there is no answer to my question I debugged further and further and it really just seems impossible to configure the Transformer-EIP with XQuery in any way. Also I was not able to find any way to load the imported xquery module from the classpath so I changed my code and now I call my xquery via the XQueryEndpoint which provides support for custom configuration:

.to("xquery:/xquery/myCoolXQuery.xquery?configuration=#saxonConfig&resultsFormat=String")

这样我的路线就可以了.但是如果能够使用 transform() 那就太好了,因为代码会更容易理解.

This way my route works. But it would have been nice to be able to use the transform() because the code would be easier to understand.

相关文章