You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Camel集成XQuery报错:参数类型不匹配问题求助

问题根源

Saxon对XQuery外部变量的类型检查极为严格,当你声明$configXML为element()类型时,要求传入的必须是关联当前查询上下文的Saxon原生XdmNode实例:

  • 直接传入org.w3c.dom.Document/Element对象时,Saxon无法将其识别为自身类型系统内的节点,会判定为外部对象
  • 即使手动创建了XdmNode,如果该实例未绑定到执行XQuery时使用的Saxon Configuration上下文,同样会触发类型不匹配报错
解决办法

1. 确保依赖版本兼容(Java 17适配)

使用支持Java 17的Camel和Saxon版本,避免版本不兼容导致的隐性问题:

<dependencies>
    <!-- Camel Core -->
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>3.20.2</version>
    </dependency>
    <!-- Camel Saxon 组件 -->
    <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-saxon</artifactId>
        <version>3.20.2</version>
    </dependency>
    <!-- Saxon HE 11.x+ 支持Java 17 -->
    <dependency>
        <groupId>net.sf.saxon</groupId>
        <artifactId>Saxon-HE</artifactId>
        <version>11.6</version>
    </dependency>
</dependencies>

2. 在Camel路由中正确转换XML为Saxon XdmNode

使用Saxon原生API将XML转换为绑定到当前Configuration的XdmNode,确保上下文一致:

import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.XdmNode;
import org.apache.camel.builder.RouteBuilder;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XQueryIntegrationRoute extends RouteBuilder {
    // 初始化Saxon Processor(单例,绑定统一Configuration)
    private final Processor saxonProcessor = new Processor(false);

    @Override
    public void configure() throws Exception {
        from("file:data/in?fileName=Config.xml")
            .process(exchange -> {
                File configFile = exchange.getIn().getBody(File.class);
                // 开启命名空间感知,避免Saxon节点类型校验失败
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                dbf.setNamespaceAware(true);
                Document domDoc = dbf.newDocumentBuilder().parse(configFile);

                // 将DOM转换为Saxon XdmNode,绑定到当前Processor的Configuration
                XdmNode xdmConfigNode = saxonProcessor.newDocumentBuilder().wrap(domDoc);
                exchange.setProperty("configXML", xdmConfigNode);
            })
            // 通过#exchangeProperties传递外部变量到XQuery
            .to("saxon:test.xqy?variables=#exchangeProperties");
    }
}

3. 验证XQuery变量声明与使用

确保XQuery中的变量声明和逻辑匹配传入的节点类型,示例test.xqy:

declare variable $configXML as element() external;

<!-- 示例逻辑:提取配置中的名称节点 -->
<processed-config>
    <name>{data($configXML/config/name)}</name>
    <timeout>{data($configXML/config/timeout)}</timeout>
</processed-config>

关键注意事项

  • 必须开启NamespaceAware:Saxon对XML命名空间处理严格,未开启会导致转换后的节点无法被识别为element()类型
  • 复用Saxon Processor:避免在每个处理器中重复创建Processor,确保所有XdmNode都绑定到同一个Configuration上下文
  • 变量传递方式:使用variables=#exchangeProperties确保Exchange属性中的XdmNode被正确传入XQuery上下文

内容的提问来源于stack exchange,提问作者user29885133

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:06:00