Kar*_*ick 3 xml xquery marklogic
我有以下节点,我想在其中添加属性到所有add
节点.
<test>
<add>x1</add>
<c><add>x2</add></c>
<b att1="x">x</b>
</test>
Run Code Online (Sandbox Code Playgroud)
我试过了
functx:add-attributes($test, xs:QName('att1'), 1)
Run Code Online (Sandbox Code Playgroud)
它可以将属性添加到test
节点.但
当我尝试
functx:add-attributes($test/add, xs:QName('att1'), 1)
Run Code Online (Sandbox Code Playgroud)
它将属性添加到第一个添加节点,但仅返回添加了属性的添加节点.然后当我尝试$test//add
它时抛出错误.
当我尝试
for $add in $test//add
return functx:add-attributes($add, xs:QName('att1'), 1)
Run Code Online (Sandbox Code Playgroud)
它分别返回两个添加节点.现在,如何重构原始节点以仅将属性添加到指定节点.
首先,我要指出,仅仅在内存中使用与更新数据库内容的方式有所不同.对于后者,您可以这样做:
for $add in $test//add
return
xdmp:node-insert-child(
$add,
attribute atta1 { 1 }
)
Run Code Online (Sandbox Code Playgroud)
要在内存中更改它,这就是functx所做的,您将制作原始文件的副本,在构建副本时对副本进行更改.这称为递归下降,是一种非常常见的模式.我刚才写了一篇博文,展示了如何实现递归下降,但实质上你会做一个类型切换,当遇到"add"元素时,会创建新属性.您可以使用functx功能.沿着这些方向的东西(未经测试):
declare function local:change($node)
{
typeswitch($node)
case element(add) return
functx:add-attributes($node, xs:QName('att1'), 1)
case element() return
element { fn:node-name($node) } {
$node/@*,
$node/node() ! local:change(.)
}
default return $node
};
Run Code Online (Sandbox Code Playgroud)
此代码假定add元素不会在其中添加元素; 如果你愿意的话,你会想做第一种情况的第二种情况.
归档时间: |
|
查看次数: |
383 次 |
最近记录: |