Function XQuery node-name()函数,它是如何工作的?
我想为每个Function XQuery node-name()函数,它是如何工作的?,function,xquery,Function,Xquery,我想为每个对添加额外的对 我有这样的代码: <data> <pair> <key>keyName1</key> <value>something1</value> </pair> <pair> <key>keyName2</key> <value>something2</value> </pair> <p
对添加额外的对
我有这样的代码:
<data>
<pair>
<key>keyName1</key>
<value>something1</value>
</pair>
<pair>
<key>keyName2</key>
<value>something2</value>
</pair>
<pair>
<key>keyName3</key>
<value>
<listOfPairs>
<pair>
<key>keyName4</key>
<value>Something6</value>
</pair>
</listOfPairs>
</value>
</pair>
<pair>
<key>keyName5</key>
<value>Something9</value>
</pair>
</data>
关键字1
有些事
关键字2
什么
关键字3
关键字4
什么
关键字5
有些事
我需要在每对之后插入其他对,无论在哪个级别,前缀为“copy”,值不同:
<data>
<pair>
<key>keyName1</key>
<value>something1</value>
</pair>
<pair>
<key>copy_keyName1</key>
<value>another1</value>
</pair>
<pair>
<key>keyName2</key>
<value>something2</value>
</pair>
<pair>
<key>copy_keyName2</key>
<value>another2</value>
</pair>
<pair>
<key>keyNamedwithLists</key>
<value>
<listOfPairs>
<pair>
<key>keyName4</key>
<value>Something6</value>
</pair>
<pair>
<key>copy_keyName4</key>
<value>Another6</value>
</pair>
</listOfPairs>
</value>
</pair>
<pair>
<key>keyName5</key>
<value>Something9</value>
</pair>
<pair>
<key>copy_keyName5</key>
<value>another9</value>
</pair>
</data>
关键字1
有些事
复制密钥名1
另一个1
关键字2
什么
复制密钥名2
另一个2
关键字名称列表
关键字4
什么
复制密钥名4
另一个6
关键字5
有些事
复制密钥名5
另一个9
为了得到这种结果,我需要使用函数:node-name()
?它是如何工作的?我应该如何使用它?或者我应该使用另一个函数?正如@jens erat提到的,您不需要node-name()
,相反,您可能需要这样的函数:
<data> {
for $pair in /data/pair
return
($pair,
<pair>
<key>{concat("copy_", $pair/key)}</key>
<value>some other value</value>
</pair>)
}</data>
{
对于$pair in/data/pair
返回
($对,
{concat(“复制”,$pair/key)}
其他价值
)
}
更新-正如您在评论中提到的,这将只复制最外层的对,如果您想复制所有对,而不管它们的深度如何,那么您需要使用递归下降来转换输入
实际上,我发现在XQuery中为您的特定用例编写这篇文章是一个相当大的挑战,尽管解决方案相当优雅,但我认为:-)如果其他人能想出更好的实现,我会感兴趣吗
xquery version "1.0";
declare function local:copy-pair($pair as element(pair), $copying) as element(pair)+ {
(
if(not($copying))then
$pair
else(),
<pair>
<key>{concat("copy_", $pair/key)}</key>
{ local:recursive-descent($pair/key/following-sibling::node(), true()) }
</pair>
)
};
declare function local:recursive-descent($nodes, $copying) {
for $node in $nodes
return
(
typeswitch($node)
case element(pair) return
local:copy-pair($node, $copying)
case element() return
element {node-name($node)} {
local:recursive-descent($node/node(), $copying)
}
case text() return
if($copying and $node/parent::value and empty($node/parent::value/element()))then
text { concat("SOME NEW VALUE. old value = ", $node) }
else
$node
default return
(
$node,
local:recursive-descent($node/node(), false())
)
)
};
local:recursive-descent(/data, false())
xquery版本“1.0”;
声明函数本地:复制对($pair作为元素(pair),$copying)作为元素(pair)+{
(
如果(不是($copying))那么
美元对
else(),
{concat(“复制”,$pair/key)}
{本地:递归下降($pair/key/following sibling::node(),true())}
)
};
声明函数本地:递归下降($nodes,$copying){
对于$node中的$node
返回
(
类型开关($node)
case元素(对)返回
本地:复制对($node,$copying)
case元素()返回
元素{node name($node)}{
局部:递归下降($node/node(),$copying)
}
case text()返回
如果($copying和$node/parent::value)为空($node/parent::value/element()),则
文本{concat(“一些新值。旧值=,$node)}
其他的
$node
默认返回
(
$node,
局部:递归下降($node/node(),false())
)
)
};
局部:递归下降(/data,false())
递归下降
函数基本上通过节点树执行从左到右的递归下降。任何名为pair
的元素都会传递给copy pair
函数,否则它只会复制元素中文本节点的副本($copying
),在这种情况下,它会为副本创建一个新的可选文本值
copy pair
函数决定是否复制原始对,这取决于我们是否已经在复制,然后创建原始对的新副本,然后它本身执行递归下降。如果您有权访问转换表达式,您可以执行以下操作:
declare function local:additional-pairs($d){
copy $c:=$d
modify(
for $p in $c//pair[not(.//pair)] (: pairs with no descendant pairs :)
return insert node
<pair>
<key>copy_{$p/key/string()}</key>
<value>some new</value>
</pair>
after $p
)
return $c
};
声明函数本地:附加对($d){
副本$c:=$d
修改(
对于$c//对中的$p[非(.//对)](:没有后代对的对:)
返回插入节点
复制{$p/key/string()}
一些新的
在$p之后
)
返回$c
};
node-name()
返回元素名称。对于/node-name()
它将返回foo
。我不明白您为什么需要它,因为您只需要访问值,而不需要访问元素名称。看起来不错,但当我放置映射时,我在data/pair[key=“keyNamedwithLists”]/value/listOfPairs/pair处获得了这一对。这一对没有任何副本。我需要那条终极之路,不管是哪条路,直到任何一对。每一对都应该得到一份。(添加:给定的映射是动态的,并且每次都会更改。)根据您的回答,他将只向那些添加additiona pairs:/data/pairy您还需要考虑pair的子级,其中值是一个对列表,可能您只需要$c//pairtanks上的谓词亚当,我做了更改。在示例中,keyName3没有在代码中复制(尽管keynameWithList变为keynamedWithList?)。