tags:

views:

428

answers:

4

So I have xml data like this:

  <PhoneNumber>213-512-7457</PhoneNumber>
  <PhoneNumber>213-512-7465</PhoneNumber>

and with this XQuery:

<PhoneNumberList>
{
  for $phone in $c//PhoneNumber
  let $phoneStr := ""
  return concat($phoneStr, $phone) 
}
</PhoneNumberList>

I get:

<PhoneNumberList>213-512-7457213-512-7465</PhoneNumberList>

But I actually want:

<PhoneNumberList>213-512-7457, 213-512-7465</PhoneNumberList>

Could someone shed some light on how to do this?

A: 

What about this?

let $phoneStr := ""
<PhoneNumberList>
{
  for $phone in $c//PhoneNumber
  let $result = concat($phoneStr, $phone)
  let $phoneStr = ", "
  return $result 
}
</PhoneNumberList>
Dmitry
i tried running that, but it still doesn't add the , ...how weird.
ShaChris23
Yes, I forgot that variables in XQuery can't be modified.
Dmitry
A: 

Ok, something like this should return the first element as-is and the rest with prepended ", "

<PhoneNumberList>
{
  for $phone in $c//PhoneNumber[0]
  return $phone
  for $phone in $c//PhoneNumber[position()>0]
  return concat(", ", $phone)
}
</PhoneNumberList>
Dmitry
You'll want a `,` between the two flwor expressions, and since these are values a space will be inserted automatically. Make these flwor expressions return text nodes and you should be there, although its not a particularly clear solution.
Oliver Hallam
+2  A: 
<PhoneNumberList>
{
    string-join($c//PhoneNumber, ", ")
}
</PhoneNumberList>
asdf
oh my god..works like magic. Thanks!
ShaChris23
A: 

There seems to be a lot of confusion with variables in XQuery. A let expression creates a new variable each time it is evaluated, so the "procedural" approaches below will not work.

Whilst the string-join solution is the best in your case, the correct way to write this "manually" is with a recursive function:

declare function local:join-numbers($numbers)
{
  concat($numbers[1], ", ", local:join-numbers(substring($numbers,2)))
};

<PhoneNumberList>
{
  local:joinNumbers($c//PhoneNumber)
}
</PhoneNumberList>
Oliver Hallam