Recursively wrapping an element

Let's say that I have an element <x>x</x>and some empty elements (<a/>, <b/>, <c/>), and I want to wrap the first of them in the second in turn, as a result we get <c><b><a><x>x</x></a></b></c>. How can I do this when I do not know the number of empty elements?

I can do

xquery version "3.0";

declare function local:wrap-up($inner-element as element(), $outer-elements as element()+) as element()+ {
    if (count($outer-elements) eq 3)
    then element{node-name($outer-elements[3])}{element{node-name($outer-elements[2])}{element{node-name($outer-elements[1])}{$inner-element}}}
    else 
        if (count($outer-elements) eq 2)
        then element{node-name($outer-elements[2])}{element{node-name($outer-elements[1])}{$inner-element}}
        else
            if (count($outer-elements) eq 1)
            then element{node-name($outer-elements[1])}{$inner-element}
            else ($outer-elements, $inner-element)
};

let $inner-element := <x>x</x>
let $outer-elements := (<a/>, <b/>, <c/>)

return 
    local:wrap-up($inner-element, $outer-elements)

but is there a way to do this through recursion, and not for parsing and parsing, but climbing and building?

+4
source share
1 answer

In functional programming, you usually try to work with the first element and the tail of the list, so the canonical solution would be to cancel the input before nesting the elements:

declare function local:recursive-wrap-up($elements as element()+) as element() {
  let $head := head($elements)
  let $tail := tail($elements)
  return
    element { name($head) } { (
      $head/@*,
      $head/node(),
      if ($tail)
      then local:recursive-wrap-up($tail)
      else ()
    ) }
};

let $inner-element := <x>x</x>
let $outer-elements := (<a/>, <b/>, <c/>)

return (
    local:wrap-up($inner-element, $outer-elements),
    local:recursive-wrap-up(reverse(($inner-element, $outer-elements)))
)

reverse(...) , XQuery. , , !

, , , , last() position() < last(). XQuery, .

, XQuery.

+5

Source: https://habr.com/ru/post/1612051/


All Articles