XQuery node-name() function, how is it work? -
i want add additional pairs each pair.
have 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 need insert other pairs after each pair no matter in level, prefix: "copy" different value:
<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 kind of result get, need use function: node-name()? how work? how should use it? ore maybe should use function?
as @jens-erat mentioned, don't need node-name(), instead presumably want this:
<data> { $pair in /data/pair return ($pair, <pair> <key>{concat("copy_", $pair/key)}</key> <value>some other value</value> </pair>) }</data> update - mentioned in comment, copy outer-most pairs, if want copy pairs no matter depth, need use recursive descent transform input.
i found writing in xquery particular use case quite challenge, although solution rather elegant think :-) interested if else can think of better implementation?
xquery version "1.0"; declare function local:copy-pair($pair element(pair), $copying) 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) { $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 , $node/parent::value , 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 left-to-right recursive-descent through node tree. element named pair passes of copy-pair function, otherwise copies apart when have copy ($copying) of text node within value element, in instance creates new alternative text value copy.
the copy-pair function determines whether copy original pair depending on if copying or not , creates new copy of original pair, performs recursive descent.
Comments
Post a Comment