XQuery 删除元素 - 属性
XQuery Remove Elements - Attributes
我有一个来自终端系统的 XML,它需要删除所有具有 empty or null
值的空元素或属性。
例子
<Element>
<fn att=""></fn>
<fn att="1"></fn>
<fn></fn>
<fn att="">
<child>1</child>
</fn>
</Element>
这是我使用 XQuery 来检查和删除它们的脚本
declare function local:remove-empty-elements($nodes as node()*) as node()* {
for $node in $nodes
return
if ($node instance of element())
then if (
(normalize-space($node) = '')
and (not(normalize-space($node/@*)))
)
then ()
else element { node-name($node)
}
{ $node/@*, local:remove-empty-elements($node/node())}
else if ($node instance of document-node())
then local:remove-empty-elements($node/node())
else $node
};
这是成功删除单个元素和标记节点。但是当我将多个属性放在一个元素中时
例如
<fn att1="Data" att2="1"></fn>
函数本身失败。
有什么实现方法吗?
之前谢谢你
** 更新 **
根据 har07 的回答,如果我想更改函数以删除具有空值的属性,有什么建议吗?我尝试使用下面的逻辑,但仍然发送相同的结果。
declare function local:remove-empty-elements($nodes as node()*) as node()* {
for $node in $nodes
return
if ($node instance of element())
then if (
(normalize-space($node) = '')
and (not($node/@*[normalize-space(.)]))
)
then (
/* updated code here */
if(($node/@*[normalize-space(.)])= '') then ()
else
$node/@*[normalize-space(.)]
)
else element { node-name($node)
}
{ $node/@*, local:remove-empty-elements($node/node())}
else if ($node instance of document-node())
then local:remove-empty-elements($node/node())
else $node
};
这部分导致了问题:
and (not(normalize-space($node/@*)))
在 单个属性 的谓词中调用 normalize-space()
函数,而不是一次将所有属性传递给函数,如下所示:
and (not($node/@*[normalize-space(.)]))
更新:
关于问题更新,您可以使用相同的谓词来过滤属性,以便您最终只得到非空属性。在inner else
块中,设置返回元素的内容如下:
else element {node-name($node)}
{
$node/@*[normalize-space(.)],
local:remove-empty-elements($node/node())
}
我有一个来自终端系统的 XML,它需要删除所有具有 empty or null
值的空元素或属性。
例子
<Element>
<fn att=""></fn>
<fn att="1"></fn>
<fn></fn>
<fn att="">
<child>1</child>
</fn>
</Element>
这是我使用 XQuery 来检查和删除它们的脚本
declare function local:remove-empty-elements($nodes as node()*) as node()* {
for $node in $nodes
return
if ($node instance of element())
then if (
(normalize-space($node) = '')
and (not(normalize-space($node/@*)))
)
then ()
else element { node-name($node)
}
{ $node/@*, local:remove-empty-elements($node/node())}
else if ($node instance of document-node())
then local:remove-empty-elements($node/node())
else $node
};
这是成功删除单个元素和标记节点。但是当我将多个属性放在一个元素中时
例如
<fn att1="Data" att2="1"></fn>
函数本身失败。
有什么实现方法吗?
之前谢谢你
** 更新 **
根据 har07 的回答,如果我想更改函数以删除具有空值的属性,有什么建议吗?我尝试使用下面的逻辑,但仍然发送相同的结果。
declare function local:remove-empty-elements($nodes as node()*) as node()* {
for $node in $nodes
return
if ($node instance of element())
then if (
(normalize-space($node) = '')
and (not($node/@*[normalize-space(.)]))
)
then (
/* updated code here */
if(($node/@*[normalize-space(.)])= '') then ()
else
$node/@*[normalize-space(.)]
)
else element { node-name($node)
}
{ $node/@*, local:remove-empty-elements($node/node())}
else if ($node instance of document-node())
then local:remove-empty-elements($node/node())
else $node
};
这部分导致了问题:
and (not(normalize-space($node/@*)))
在 单个属性 的谓词中调用 normalize-space()
函数,而不是一次将所有属性传递给函数,如下所示:
and (not($node/@*[normalize-space(.)]))
更新:
关于问题更新,您可以使用相同的谓词来过滤属性,以便您最终只得到非空属性。在inner else
块中,设置返回元素的内容如下:
else element {node-name($node)}
{
$node/@*[normalize-space(.)],
local:remove-empty-elements($node/node())
}