eclipsexqueryoracle-service-bus

Completed Xquery for multiple for loops


I have the input request like below

<Input>
<BusinessObjects>
      <BusinessObject>
        <BusinessIdentifiers>
          <BusinessIdentifier>
            <BKey>BuCode</BKey>
            <BValue>CDC</BValue>
          </BusinessIdentifier>
          <BusinessIdentifier>
            <BKey>BuType</BKey>
            <BValue>123</BValue>
          </BusinessIdentifier>
          <BusinessIdentifier>
            <BKey>CsmNo</BKey>
            <BValue>857895</BValue>
          </BusinessIdentifier>
        </BusinessIdentifiers>
       </BusinessObject>
      <BusinessObject>
        <BusinessIdentifiers>
          <BusinessIdentifier>
            <BKey>BuCode</BKey>
            <BValue>CDC</BValue>
          </BusinessIdentifier>
          <BusinessIdentifier>
            <BKey>BuType</BKey>
            <BValue>123</BValue>
          </BusinessIdentifier>
          <BusinessIdentifier>
            <BKey>CsmNo</BKey>
            <BValue>34567</BValue>
          </BusinessIdentifier>
        </BusinessIdentifiers>
        </BusinessObject>      
    </BusinessObjects>
    </Input>

i need to form an output like below schema

<Output>
<BusinessObject>
<BIKey></BIKey>
<BKey></BIKey>
<Bvalue></Bvalue>
<BOID></BOID>
</BusinessObject>
</Output>

For the above payload The output should be

<Output>
<BusinessObjects>
<BusinessObject>
<BIKey>CDC:123:857895|CDC:123:34567</BIKey>
<BKey>BUCode</BKey>
<Bvalue>CDC</Bvalue>
<BOID>CDC:123:857895</BOID>
</BusinessObject>
<BusinessObject>
<BIKey>CDC:123:857895|CDC:123:34567</BIKey>
<BKey>BUtype</BKey>
<Bvalue>123</Bvalue>
<BOID>CDC:123:857895</BOID>
</BusinessObject>
<BusinessObject>
<BIKey>CDC:123:857895|CDC:123:34567</BIKey>
<BKey>CSMNo</BKey>
<Bvalue>857895</Bvalue>
<BOID>CDC:123:857895</BOID>
</BusinessObject>
<BusinessObject>
<BIKey>CDC:123:857895|CDC:123:34567</BIKey>
<BKey>BUCode</BKey>
<Bvalue>CDC</Bvalue>
<BOID>CDC:123:34567</BOID>
</BusinessObject>
<BusinessObject>
<BIKey>CDC:123:857895|CDC:123:34567</BIKey>
<BKey>BUtype</BKey>
<Bvalue>123</Bvalue>
<BOID>CDC:123:34567</BOID>
</BusinessObject>
<BusinessObject>
<BIKey>CDC:123:857895|CDC:123:34567</BIKey>
<BKey>CSMNo</BKey>
<Bvalue>857895</Bvalue>
<BOID>CDC:123:34567</BOID>
</BusinessObject>
</BusinessObjects>
</Output>

i have tried below Xquery to get the same but ended up with errors or not meeting the requiremnt

<Ouput>
<BusinessObjects>
{
for $bi in Input/BusinessObjects/BusinessObject/BusinessIdentifiers/BusinessIdentifier
return
<BIKey>
    {
        string-join(
            for $bo in Input/BusinessObjects/BusinessObject return string-join($bo/BusinessIdentifiers/BusinessIdentifier/BValue, '|'),
            ':'
        )
    }
    </BIKey>
    <BKey>data {$bi/Bkey}</BKey>
    <Bvalue>data {$bi/Bvalue}</Bvalue>
    for $bo in Input/BusinessObjects/BusinessObject return <BOID>{string-join($bo//BValue, ':')}<BOID>

}
</BusinessObjects>
</Ouput>

the description for the output fields as follows BIKey-->it has formed with all the Bvalues of 'Business Identifier' concatenated with ':' and then for each businessobject it is separed with '|' Bkey-->Straight mapping with bkey Bvalue-->Straight mapping with Bvalue BOID--> it has to formed for each businessobject, need to concatenate the values Bvalues of Business Identifiers with ':' Any suggestions, i believe that i have to two complex loops in here, but not able to crack it.

Thanks


Solution

  • With the query

    <Output>
        <BusinessObjects>
            {
                //BusinessIdentifier 
                ! 
                <BusinessObject>
                    <BIKey>{string-join(ancestor::BusinessObjects/BusinessObject!string-join(.//BValue, ':'), '|')}</BIKey>
                    {
                        BKey, 
                        BValue
                    }
                    <BOID>{ancestor::BusinessObject!string-join(.//BValue, ':')}</BOID>
                </BusinessObject>
            }
        </BusinessObjects>
    </Output>
    

    at https://xqueryfiddle.liberty-development.net/948Fn5g I get the result

    <Output>
       <BusinessObjects>
          <BusinessObject>
             <BIKey>CDC:123:857895|CDC:123:34567</BIKey>
             <BKey>BuCode</BKey>
             <BValue>CDC</BValue>
             <BOID>CDC:123:857895</BOID>
          </BusinessObject>
          <BusinessObject>
             <BIKey>CDC:123:857895|CDC:123:34567</BIKey>
             <BKey>BuType</BKey>
             <BValue>123</BValue>
             <BOID>CDC:123:857895</BOID>
          </BusinessObject>
          <BusinessObject>
             <BIKey>CDC:123:857895|CDC:123:34567</BIKey>
             <BKey>CsmNo</BKey>
             <BValue>857895</BValue>
             <BOID>CDC:123:857895</BOID>
          </BusinessObject>
          <BusinessObject>
             <BIKey>CDC:123:857895|CDC:123:34567</BIKey>
             <BKey>BuCode</BKey>
             <BValue>CDC</BValue>
             <BOID>CDC:123:34567</BOID>
          </BusinessObject>
          <BusinessObject>
             <BIKey>CDC:123:857895|CDC:123:34567</BIKey>
             <BKey>BuType</BKey>
             <BValue>123</BValue>
             <BOID>CDC:123:34567</BOID>
          </BusinessObject>
          <BusinessObject>
             <BIKey>CDC:123:857895|CDC:123:34567</BIKey>
             <BKey>CsmNo</BKey>
             <BValue>34567</BValue>
             <BOID>CDC:123:34567</BOID>
          </BusinessObject>
       </BusinessObjects>
    </Output>
    

    In XQuery 1 you don't have the ! simple map operator but you should be able to use for .. return instead, see https://xqueryfiddle.liberty-development.net/948Fn5g/1 with

    <Output>
        <BusinessObjects>
            {
                for $bi in //BusinessIdentifier 
                return  
                <BusinessObject>
                    <BIKey>{string-join($bi/ancestor::BusinessObjects/BusinessObject/string-join(.//BValue, ':'), '|')}</BIKey>
                    {
                        $bi/BKey, 
                        $bi/BValue
                    }
                    <BOID>{$bi/ancestor::BusinessObject/string-join(.//BValue, ':')}</BOID>
                </BusinessObject>
            }
        </BusinessObjects>
    </Output>
    

    or simple steps constructing a new element, see https://xqueryfiddle.liberty-development.net/948Fn5g/2 with

    <Output>
        <BusinessObjects>
            {
                //BusinessIdentifier/
                <BusinessObject>
                    <BIKey>{string-join(ancestor::BusinessObjects/BusinessObject/string-join(.//BValue, ':'), '|')}</BIKey>
                    {
                        BKey, 
                        BValue
                    }
                    <BOID>{ancestor::BusinessObject/string-join(.//BValue, ':')}</BOID>
                </BusinessObject>
            }
        </BusinessObjects>
    </Output>