升级Camel与Saxon后XQuery报xmlns命名空间错误求助
嘿,我之前也碰到过类似的Camel和Saxon版本升级后命名空间的问题,给你梳理下原因和解决办法:
问题到底出在哪?
你升级到Camel 2.21 + Saxon 9.8后出现的Misdeclaration of xmlns namespace错误,核心原因是Saxon 9.8对特殊命名空间的校验变得更严格了——xmlns是XML里用来定义命名空间的保留前缀,Saxon不允许把它当作普通命名空间来手动声明。
而Camel 2.21的XQueryBuilder在初始化XQuery上下文时,会默认把路由里所有的命名空间(包括xmlns本身)都传递给Saxon,这就触发了Saxon的校验规则,直接抛出了异常,导致XQueryExpression初始化失败变成null。
从错误堆栈也能看出来:异常是在StaticQueryContext.declareNamespace方法里抛出来的,正好对应Camel传递xmlns命名空间的操作。
怎么解决?
给你几个可行的解决办法,按推荐程度排序:
1. 让Camel排除xmlns命名空间
最简单的方式是在XQuery组件配置里,明确告诉Camel不要把xmlns这个特殊命名空间传递给Saxon。如果是Spring XML配置,修改你的transform节点:
<transform> <xquery excludeNamespaces="xmlns" resource:file="{{choregraphies.resources.directory}}/LINCASA1/xquery/getTypApr_request.xquery"/> </transform>
如果用Java DSL的话,就这么写:
XQueryBuilder.xQuery("resource:file:...").excludeNamespaces("xmlns")
2. 关闭自动传递命名空间的功能
如果排除单个命名空间不够用,你可以直接关闭Camel自动传递路由命名空间到XQuery的功能,设置enableNamespaces="false":
<transform> <xquery enableNamespaces="false" resource:file="{{choregraphies.resources.directory}}/LINCASA1/xquery/getTypApr_request.xquery"/> </transform>
⚠️ 注意:这么做会停止传递所有路由上下文的命名空间,如果你XQuery里需要用到其他路由里的命名空间,得手动在XQuery文件里重新声明。
3. 检查XQuery文件的命名空间(防坑)
虽然你的XQuery代码看起来没问题,但还是确认下:绝对不要在XQuery里写declare namespace xmlns="..."这种代码,Saxon 9.8会直接拒绝这种写法。你的现有代码是合规的,这一步主要是排查隐性问题。
4. 临时降级Saxon(万不得已才用)
如果上面的配置都没法快速生效,你可以临时把Saxon降级到9.7.x版本——这个版本对xmlns命名空间的校验没那么严格。但这只是临时方案,长期来看还是建议适配新版本的Saxon。
验证方法
改完配置后重启应用,触发对应的路由:
- 看看还会不会弹出
Misdeclaration of xmlns namespace的错误 - 确认XQuery能正常生成
<com:getTypApr>节点,并且能正确读取$in.headers里的prmId和id参数
内容的提问来源于stack exchange,提问作者Roy9590

