0

I have an XML document:

<resultsets>
    <row>
        <emp_no>10001</emp_no>
        <first_name>Georgi</first_name>
        <last_name>Facello</last_name>
    </row>
    <row>
        <emp_no>10002</emp_no>
        <first_name>Bezalel</first_name>
        <last_name>Simmel</last_name>
    </row>
    <row>
        <emp_no>10003</emp_no>
        <first_name>Parto</first_name>
        <last_name>Bamford</last_name>
    </row>
</resultsets>

Currently, my code is as follows:

let $first := doc("db/apps/flowq/index/employees.xml")//first_name
let $last := doc("db/apps/flowq/index/employees.xml")//last_name

My question is, is it possible ONLY use $first and $last to generate the following result?

<row>
    <first_name>Georgi</first_name>
    <last_name>Facello</last_name>
 </row>
 <row>
    <first_name>Bezalel</first_name>
    <last_name>Simmel</last_name>
 </row>
 <row>
    <first_name>Parto</first_name>
    <last_name>Bamford</last_name>
 </row>

Basically, if we have two lists of nodes same size, how can we merge them one by one? I have tried ($first_name, $last_name) and ($first_name union $last_name) but doesn't work,

thanks!

Judah Flynn
  • 544
  • 1
  • 8
  • 20

2 Answers2

3

And of course for FP afficionados there's the basic recursive function:

declare function local:merge($s1, $s2) {
  if ($s1 and $s2) 
  then (<row>{head($s1), head($s2)}</row>, 
        local:merge(tail($s1), tail($s2)))
  else ()
}
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
1

It is a bit odd that you first extract the two different sequences from the same document but in general if you want positional merging then using for $item at $pos can help:

let $first := (
    <first_name>Georgi</first_name>,
    <first_name>Bezalel</first_name>,
    <first_name>Parto</first_name>),
$second := (
    <last_name>Facello</last_name>,
    <last_name>Simmel</last_name>,
    <last_name>Bamford</last_name>
    )
return for $name at $pos in $first
       return
          <row>
              {$name, $second[$pos]}
          </row>

http://xqueryfiddle.liberty-development.net/eiQZDbb

Or use higher-order for-each-pair:

let $first := (
    <first_name>Georgi</first_name>,
    <first_name>Bezalel</first_name>,
    <first_name>Parto</first_name>),
$second := (
    <last_name>Facello</last_name>,
    <last_name>Simmel</last_name>,
    <last_name>Bamford</last_name>
    )
return for-each-pair($first, $second, function($f, $s) { <row>{$f, $s}</row>})
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110