如何将属性添加到节点的所有特定子节点
How to add attribute to all particular children of a node
我有以下节点,我想在其中向所有 add
个节点添加属性。
<test>
<add>x1</add>
<c><add>x2</add></c>
<b att1="x">x</b>
</test>
我试过了
functx:add-attributes($test, xs:QName('att1'), 1)
可以将属性添加到test
节点。但是
当我尝试时
functx:add-attributes($test/add, xs:QName('att1'), 1)
它将属性添加到第一个添加节点,但returns仅添加具有添加属性的节点。然后,当我尝试使用 $test//add
时,它会抛出错误。
当我尝试时
for $add in $test//add
return functx:add-attributes($add, xs:QName('att1'), 1)
它returns两个单独添加节点。现在,如何重组原始节点以仅将属性添加到指定节点。
首先,让我指出,仅在内存中使用与更新数据库内容的方式有所不同。对于后者,你可以这样做:
for $add in $test//add
return
xdmp:node-insert-child(
$add,
attribute atta1 { 1 }
)
要在内存中更改它,这就是 functx 所做的,您将制作原始副本,并在构建副本时对副本进行更改。这称为递归下降,是一种非常常见的模式。我不久前写了一篇博客 post,其中显示了 how to implement recursive descent,但本质上您将执行一个类型切换,当遇到 "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
};
此代码假设 add 元素内部没有 add 元素;如果你愿意,那么你会想为第一种情况做类似第二种情况的事情。
您可以通过两种方式 replace/insert/delete 元素或属性。
内存中更改或更改数据库的实际内容。
由于您不想更改数据库中的值,因此可以使用内存中的文档更新。
import module namespace mem = "http://xqdev.com/in-mem-update" at "/MarkLogic/appservices/utils/in-mem-update.xqy";
您可以使用 xdmp:node-insert-child()
而不是
mem:node-insert-child(<x/>, <y/>)
我有以下节点,我想在其中向所有 add
个节点添加属性。
<test>
<add>x1</add>
<c><add>x2</add></c>
<b att1="x">x</b>
</test>
我试过了
functx:add-attributes($test, xs:QName('att1'), 1)
可以将属性添加到test
节点。但是
当我尝试时
functx:add-attributes($test/add, xs:QName('att1'), 1)
它将属性添加到第一个添加节点,但returns仅添加具有添加属性的节点。然后,当我尝试使用 $test//add
时,它会抛出错误。
当我尝试时
for $add in $test//add
return functx:add-attributes($add, xs:QName('att1'), 1)
它returns两个单独添加节点。现在,如何重组原始节点以仅将属性添加到指定节点。
首先,让我指出,仅在内存中使用与更新数据库内容的方式有所不同。对于后者,你可以这样做:
for $add in $test//add
return
xdmp:node-insert-child(
$add,
attribute atta1 { 1 }
)
要在内存中更改它,这就是 functx 所做的,您将制作原始副本,并在构建副本时对副本进行更改。这称为递归下降,是一种非常常见的模式。我不久前写了一篇博客 post,其中显示了 how to implement recursive descent,但本质上您将执行一个类型切换,当遇到 "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
};
此代码假设 add 元素内部没有 add 元素;如果你愿意,那么你会想为第一种情况做类似第二种情况的事情。
您可以通过两种方式 replace/insert/delete 元素或属性。 内存中更改或更改数据库的实际内容。 由于您不想更改数据库中的值,因此可以使用内存中的文档更新。
import module namespace mem = "http://xqdev.com/in-mem-update" at "/MarkLogic/appservices/utils/in-mem-update.xqy";
您可以使用 xdmp:node-insert-child()
而不是
mem:node-insert-child(<x/>, <y/>)