developers

    Forum Stats

  • 3,873,880 Users
  • 2,266,627 Discussions
  • 7,911,650 Comments

Discussions

How to Avoid Nested 'for' Loops

vv*338251*hu
vv*338251*hu Member Posts: 49
edited Jul 2, 2013 8:05AM in XQuery

Hi,

We were trying with complex transformation where it requires to have nested for loop. To explain in details the source xml is like below

Input:

<?xml version="1.0"?>

<Items xmlns="http://www.example.org/Item">

<Item cat="ItemBean">

<UniqueId>2</UniqueId>

<ParentId>1</ParentId>

</Item>

<Item cat="ItemBean">

<UniqueId>4</UniqueId>

<ParentId>1</ParentId>

</Item>

<Item cat="ProductBean">

<UniqueId>1</UniqueId>

<Name>Device1</Name>

</Item>

<Item cat="ProductBean">

<UniqueId>3</UniqueId>

<Name>Device2</Name>

</Item> 

</Items>

The expected response is like in below

<Devices xmlns="http://www.example.org/Item">

<Device name="Device1">

<DeviceItem>

<Name>ItemBean</Name>

<UniqueId>2</UniqueId>

<ParentId>1</ParentId>

</DeviceItem>

<DeviceItem>

<Name>ItemBean</Name>

<UniqueId>4</UniqueId>

<ParentId>1</ParentId>

</DeviceItem>

</Device>

<Device name="Device2">

</Device>

</Devices>

I was tring something like below transformation, it is working. But looks to be performance cause as i have nested for loops. How can it be imprved by not having nested loops

Mapper:

declare function xf:nextedLoop($itemPayload as element(ns0:Items)) as element(ns0:Devices) {
<ns0:Devices>
        {
        for $productId in $itemPayload/ns0:Item[@cat='ProductBean']
        return
        <ns0:Device name="{data($productId/ns0:Name)}">
{
 for $itemId in $itemPayload/ns0:Item[@cat='ItemBean' and ns0:ParentId = data ($productId/ns0:UniqueId)]
        return 
               <ns0:DeviceItem>
               <ns0:Name>ItemBean</ns0:Name>
       <ns0:UniqueId>{data ($itemId/ns0:UniqueId)}</ns0:UniqueId>
       <ns0:ParentId>{data ($productId/ns0:UniqueId)}</ns0:ParentId>
         </ns0:DeviceItem>
        }
</ns0:Device>
}
        </ns0:Devices>
};

Here is the Schema

:

 
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Item" xmlns:tns="http://www.example.org/Item" elementFormDefault="qualified">

 <element name="Items" type="tns:items" />

 <complexType name="items">
  <sequence>
   <element name="Item" type="tns:item" maxOccurs="unbounded" />
  </sequence>
 </complexType>

 <complexType name="item">
  <sequence>
   <element name="UniqueId" type="string"></element>
   <element name="ParentId" type="string" minOccurs="0"></element>
   <element name="Name" type="string" minOccurs="0"></element>
  </sequence>
  <attribute name="cat" type="string"></attribute>  
 </complexType>

 <element name="Devices" type="tns:devices" />

 <complexType name="devices">
  <sequence>
   <element name="Device" type="tns:device" maxOccurs="unbounded" />
  </sequence>
 </complexType>

 <complexType name="device">
  <sequence>
   <element name="DeviceItem" type="tns:deviceItem" maxOccurs="unbounded"></element>   
  </sequence>
  <attribute name="name" type="string"></attribute>  
 </complexType>

 <complexType name="deviceItem">
  <sequence>
   <element name="Name" type="string"></element>   
   <element name="UniqueId" type="string"></element>
   <element name="ParentId" type="string"></element>
  </sequence>    
 </complexType>
</schema>

Thanks

Venkata Madhu

Answers

  • vv*338251*hu
    vv*338251*hu Member Posts: 49

    Hi All,

    I was tring using every function, but not able to get the expected results. Any idea?

    declare function xf:SomeOmniXQ($itemPayload as element(ns0:Items))
        as element(ns0:Devices) {
            <ns0:Devices>
            {
             for $productBean in $itemPayload/ns0:Item[@cat='ProductBean']
             return
              <ns0:Device name="{data($productBean/ns0:Name)}">          
               return
               {                       
                if (every $itemBean in $itemPayload/ns0:Item[@cat='ItemBean'] satisfies  $itemBean/ns0:ParentId/text() = $productBean/ns0:UniqueId/text()) then
                
                 <ns0:Device>
                  <ns0:Name>ItemBean</ns0:Name>
            <ns0:UniqueId> $itemBean/ns0:UniqueId/text() </ns0:UniqueId>
            <ns0:ParentId> $productBean/ns0:UniqueId/text() </ns0:ParentId>
                 </ns0:Device>            
                else () 
            }          
              </ns0:Device>        
            }
            </ns0:Devices>
    };
    

    Thanks

    Venkata Madhu

This discussion has been closed.
developers