如何将属性添加到节点的所有特定子级 [英] How to add attribute to all particular children of a node
问题描述
我有一个下面的节点,我想在其中向所有add
节点添加属性.
I have the following node in which I want to add attribute to all add
nodes.
<test>
<add>x1</add>
<c><add>x2</add></c>
<b att1="x">x</b>
</test>
我尝试过
functx:add-attributes($test, xs:QName('att1'), 1)
它可以将属性添加到test
节点.但是
It can add the attribute to the test
node. But
当我尝试
functx:add-attributes($test/add, xs:QName('att1'), 1)
它将属性添加到第一个添加节点,但仅返回具有添加属性的添加节点.然后,当我尝试使用$test//add
时,它将引发错误.
It added the attribute to the first add node but returns only add node with added attribute. Then when I tried with $test//add
it throws error.
当我尝试
for $add in $test//add
return functx:add-attributes($add, xs:QName('att1'), 1)
它分别返回两个添加节点.现在,如何重构原始节点以将属性仅添加到指定的节点.
It returns two add nodes individually. Now, how to restructure the original node to add the attributes to only the specified nodes.
推荐答案
首先,让我指出,仅用于内存使用和更新数据库内容的方式有所不同.对于后者,您可以执行以下操作:
First, let me point out that there is a difference in how this is done for just in-memory use versus updating the content of the database. For the latter, you could do:
for $add in $test//add
return
xdmp:node-insert-child(
$add,
attribute atta1 { 1 }
)
要在内存中进行更改,这就是functx所做的,您将制作原始文件的副本,并在构建副本时对其进行更改.这称为递归下降,是一种很常见的模式.不久前,我写了一篇博客文章,内容显示了如何实现递归下降,但是本质上,您将执行一个typeswitch,当它遇到"add"元素时,将创建新属性.您可以使用functx函数.遵循以下原则(未经测试):
To change it in memory, which is what functx does, you'll be making a copy of the original, making changes in the copy as you build it. This is called recursive descent and is a pretty common pattern. I wrote a blog post a while ago that shows how to implement recursive descent, but essentially you'll do a typeswitch that, when it encounters an "add" element, creates the new attribute. You can use the functx function for that. Something along these lines (untested):
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
};
此代码假定add元素内部没有add元素;如果愿意的话,那么您想为第一种情况做类似第二种情况的操作.
This code assumes that an add element won't have add elements inside of it; if you will, then you'd want to do something like the second case for the first.
这篇关于如何将属性添加到节点的所有特定子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!