Berkeley dbXML 6.0 XQuery查询:统一同命名空间的不同前缀
解决Berkeley dbXML 6.0中XQuery统一命名空间前缀的问题
直接引用原文档节点会保留其自带的前缀声明,导致结果里混杂ns0/ns1前缀。要统一使用外层的ns2前缀,需要重新构造目标命名空间的元素,而不是直接插入原节点。
基础解决方案(适用于无嵌套同命名空间元素的场景)
修改XQuery,遍历匹配元素后重新生成带ns2前缀的元素,复制原节点的内容:
<Result xmlns:ns2="http://my.url"> { for $doc in collection("my_collection")/*[namespace-uri() = "http://my.url" and local-name() = "a"] return <Return> <ns2:a> {$doc/node()} {$doc/@*} </ns2:a> </Return> } </Result>
关键说明:
- 用
namespace-uri() = "http://my.url" and local-name() = "a"匹配元素:不依赖原文档的前缀,确保命中所有目标命名空间下的<a>元素 - 重新构造
<ns2:a>:该元素会继承外层<Result>的命名空间声明,自动使用ns2前缀 $doc/node()复制原元素的所有子节点(文本、子元素等),$doc/@*复制所有属性(如果原元素存在属性)
递归解决方案(适用于含嵌套同命名空间元素的场景)
如果原<a>元素下还有同命名空间的嵌套元素,需要递归转换所有目标命名空间的元素,统一前缀:
declare function local:convert-node($node as node()) as node()* { typeswitch ($node) case element() return if (namespace-uri($node) = "http://my.url") then element ns2:{local-name($node)} { $node/@*, local:convert-node($node/node()) } else element {node-name($node)} { $node/@*, local:convert-node($node/node()) } case text() | comment() | processing-instruction() return $node default return $node }; <Result xmlns:ns2="http://my.url"> { for $doc in collection("my_collection")/*[namespace-uri() = "http://my.url" and local-name() = "a"] return <Return> {local:convert-node($doc)} </Return> } </Result>
关键说明:
- 自定义递归函数
local:convert-node:遍历所有节点,对目标命名空间的元素重新构造为ns2前缀,其他节点(文本、注释、其他命名空间元素)保持原样 - 确保所有嵌套的同命名空间元素都统一使用ns2前缀,彻底解决前缀混杂问题
内容的提问来源于stack exchange,提问作者Marie R
相关产品推荐
相关产品推荐

