Search code examples
xmlxquerytokenizeosb

Xquery - walking two sequences in parallel


I am trying to turn the results of 2 strings from:

<string1>A,B,C</string1>
<string2>1,2,3</string2>

to

<result1>
  <value1>A</value1>
  <value1>1</value1>
</result1>

<result2>
  <value1>B</value1>
  <value1>2</value1>
</result2>

<result3>
  <value1>C</value1>
  <value1>3</value1>
</result3>

I can tokenize each string to separate each value but I have a problem then combining the results

i.e the first result in string1 needs to be paired with the first result in string2, the second result in string2 needs to be paired with the second result in string 2 and so on. Any help would be much appreciated


Solution

  • The basic approach is to walk through the two sequences of tokens together. For example:

    let $string1 := <string1>A,B,C</string1>, 
        $string2 := <string2>1,2,3</string2>
    
    let $letters := tokenize($string1, ','),
        $numbers := tokenize($string2, ',')
    
    return if (count($letters) ne count($numbers)) then
        'Oops, mismatched sets of strings, please try again'
    else
        for $s at $pos in $letters
        return <result>
          <value>{$letters[$pos]}</value>
          <value>{$numbers[$pos]}</value>
        </result>
    

    Or you can formulate the for expression as for $pos in 1 to count($letters).

    Note that these produce sequences of elements all named result, not result1, result2, etc., and the children are named value, not value1, because I can't bring myself to take that part of the problem description seriously. If you are not yet in a position to tell the difference between the first result element in a sequence and the third without having the name tell you where it was, then it's worth while to spend some time acquiring that ability.