如何在不使用XQuery更新的前提下替换空字符串为'empty'元素
递归替换空字符串为
<empty>元素的非XQuery Update方案 Got it! 既然你已经用XQuery Update搞定了空字符串替换成<empty>元素的需求,但现在想找不依赖XQuery Updating的递归实现,那我直接给你上实用的代码和思路吧~
核心思路
递归遍历XML文档的每一个节点,做针对性处理:
- 文本节点:如果是空字符串,替换为
<empty/>元素;否则保留原文本 - 元素节点:保留原元素名和属性,递归处理所有子节点
- 其他节点(注释、处理指令等)直接返回原节点,不做修改
基础实现代码
declare function local:replace-empty-strings($node as node()) as node() { typeswitch ($node) -- 处理文本节点:空字符串替换为<empty>元素 case text() return if ($node eq '') then <empty/> else $node -- 处理元素节点:递归处理子节点,保留原属性 case element() return element { node-name($node) } { $node/@*, for $child in $node/node() return local:replace-empty-strings($child) } -- 其他节点直接返回 default return $node }; -- 调用示例:传入你的XML文档节点 -- local:replace-empty-strings($your-input-xml)
扩展优化:处理纯空白文本与属性空值
1. 替换纯空白文本
如果需要把全是空格、换行、制表符的纯空白文本也替换成<empty>元素,可以把文本节点的判断条件改成:
if (normalize-space($node) eq '') then <empty/> else $node
normalize-space()会去掉文本首尾的空白并把中间的连续空白合并,所以如果处理后是空字符串,说明原文本是纯空白。
2. 处理属性中的空值
属性值不能包含XML元素,所以如果属性值为空,只能替换成字符串值(比如'empty')。修改元素节点的属性处理部分即可:
case element() return element { node-name($node) } { -- 处理属性空值 for $attr in $node/@* return if ($attr eq '') then attribute { node-name($attr) } { 'empty' } else $attr, -- 递归处理子节点 for $child in $node/node() return local:replace-empty-strings($child) }
这个方案完全不依赖XQuery Updating,纯靠递归节点遍历实现,兼容性更好,能在不支持Update特性的XQuery环境中运行~
内容的提问来源于stack exchange,提问作者SS2
相关产品推荐
相关产品推荐

