Forum Stats

  • 3,875,109 Users
  • 2,266,806 Discussions
  • 7,912,085 Comments

Discussions

Need help with non-repeating to repeating XQuery transformation

user8958419
user8958419 Member Posts: 81
edited Nov 25, 2013 7:26AM in XQuery

I have a non-repeating source:

<Address>

<Phone1>999-888-7777</Phone1>

<Phone1Extn>1234</Phone1Extn>

<Phone2>111-222-3333</Phone2>

<Phone2Extn></Phone2Extn>

</Address>

The Target should be

<PhoneList>

<Phone> 

<PhoneCode> Work</PhoneCode>

<PhoneNumber> 999-888-7777</PhoneNumber>

<PhoneExtension>1234</PhoneExtension>

</Phone>

<Phone> 

<PhoneCode> Home</PhoneCode>

<PhoneNumber> 111-222-3333</PhoneNumber>

<PhoneExtension></PhoneExtension>

</Phone>

</PhoneList>

How do I write the xQuery to accomplish this? I tried with "union" on Phone1, Phone2, I am able to get the repeating PhoneNumber but not getting the PhoneExtension.

Answers

  • tsuji
    tsuji Member Posts: 179 Bronze Badge
    edited Nov 25, 2013 6:48AM

    Suppose you have some context node or if that is the whole document, the document root ($context, say), you can do this.

    (: supposing some context, $context :)

    <PhoneList> {

    for $phone in $context/Address/(Phone1, Phone2)

    return

    <Phone>

      <PhoneCode>{

        let $name:=local-name($phone)

        return

        (

        if ($name = 'Phone1') then

          'Work'

       else

          if ($name = 'Phone2') then

            'Home'

          else ()

       )

      }</PhoneCode>

      <PhoneNumber>{$phone/text()}</PhoneNumber>

      <PhoneExtension>{$phone/following-sibling::*[1]/text()}</PhoneExtension>

    </Phone>

    }</PhoneList>

    ps Edited. I overlooked you have a PhoneCode in the output as well. Add back the block for PhoneCode. Edited-2: Further eliminated some typos. Sorry!

  • odie_63
    odie_63 Member Posts: 8,493 Silver Trophy
    edited Nov 25, 2013 7:31AM

    Based on the input you've given us, the structure appears to be fixed and known at parse time, so why not use a direct mapping :

    element PhoneList {
       element Phone { 
         element PhoneCode { "Work" }
       , element PhoneNumber { $context/Address/Phone1/text() }
       , element PhoneExtension { $context/Address/Phone1Extn/text() } 
       }
     , element Phone { 
         element PhoneCode { "Home" }
       , element PhoneNumber { $context/Address/Phone2/text() }
       , element PhoneExtension { $context/Address/Phone2Extn/text() } 
       }
    }
    
    

    (using Tsuji's convention about the context item)

This discussion has been closed.