简体   繁体   English

XQuery node-name()函数,它如何工作?

[英]XQuery node-name() function, how is it work?

I want add additional pairs for each pair . 我想为每pair添加其他对。
I have this kind of code: 我有这种代码:

<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>

and I need insert other pairs after each pair no matter in which level, with prefix: "copy" with different value: 并且我需要在每对之后插入其他对,无论处于哪个级别,其前缀为“ 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>

For this kind of result to get, i need to use function: node-name() ? 为了获得这种结果,我需要使用功能: node-name() How does it work? 它是如何工作的? How I should use it? 我应该如何使用它? Ore maybe I should use another function? 矿石也许我应该使用其他功能?

As @jens-erat mentioned, you don't need node-name() , instead presumably you want something like this: 如@ 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>

UPDATE - As you mentioned in your comment, that will only copy the outer-most pairs, if you want to copy all pairs no matter their depth, then you need to use a recursive descent to transform the input. 更新-正如您在评论中提到的那样,这只会复制最外面的对,如果要复制所有对而不管它们的深度,那么您需要使用递归下降来转换输入。

I actually found writing this in XQuery for your particular use case quite a challenge, although the solution is rather elegant I think :-) I would be interested if anyone else can think of a better implementation? 实际上,我发现针对您的特定用例在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())

The recursive-descent function basically does a left-to-right recursive-descent through the node tree. recursive-descent函数基本上通过节点树从左向右递归下降。 Any element named pair it passes of to the copy-pair function, otherwise it just copies everything apart from when we have a copy ( $copying ) of a text node within a value element, in this instance it creates a new alternative text value for the copy. 它传递给copy-pair函数的任何名为pair元素,否则它会复制所有内容,除了在value元素中有文本节点的副本( $copying )时,在这种情况下,它将为创建新的替代文本值副本。

The copy-pair function determines whether to copy the original pair depending on if we are already copying or not and then creates the new copy of the original pair, it then itself performs a recursive descent. copy-pair函数根据是否已经复制而确定是否复制原始对,然后创建原始对的新副本,然后它本身执行递归下降。

If you have access to XQuery update and the transform expression you can do something like: 如果您有权访问XQuery更新和转换表达式,则可以执行以下操作:

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
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM