To add an xsl:for-each statement using drag and drop:

  1. In the Components window, select the XSLT Elements page.

  2. Expand the Flow Control section. You can click the plus sign (+) next to Flow Control to expand the section.

  3. Drag the for-each icon to the right side of the target node until you can see the green highlighting, as shown in Figure 41-21.

    Figure 41-21 Dragging the for-each Icon to the Target Node

    Description of Figure 41-21 follows
    Description of "Figure 41-21 Dragging the for-each Icon to the Target Node"
  4. Drop the for-each icon while the green highlighting is visible. An xsl:for-each node is added as the parent node of the target node.

  5. To set the source node-set to loop over, drag and drop the source node to the xsl:for-each statement, as shown in Figure 41-20.

When viewed in the source view, the xsl:for-each statement looks similar to the following:

<ShippedItems>
  <xsl:for-each select="/ns0:PurchaseOrder/Items/HighPriorityItems/Item">
     <Item/>
  </xsl:for-each>
</ShippedItems>

Note that the Item node, created inside the xsl:for-each statement, is an empty node. You can map elements under the target Item node to set values for them.

For example, as shown in Figure 41-22, if you drag and drop Qty to Quantity, the value of the Qty element is copied to the Quantity element in the output.

Figure 41-22 Mapping Qty to Quantity

Description of Figure 41-22 follows
Description of "Figure 41-22 Mapping Qty to Quantity"

The following example shows the resulting code in source view. It also shows a sample source document and output document snippet.

<ShippedItems>
  <xsl:for-each select="/ns0:PurchaseOrder/Items/HighPriorityItems/Item">
    <Item>
      <Quantity>
        <xsl:value-of select="Qty"/>
      </Quantity>
    </Item>
  </xsl:for-each>
</ShippedItems>

The following snippet shows some sample values for the source document:

<HighPriorityItems>
     <Item PartNum="000-AA">
          <Qty>20</Qty>
     </Item>
     <Item PartNum="000-AB">
          <Qty>24</Qty>
     </Item>
</HighPriorityItems>

The following snippet shows the output values corresponding to the preceding source document:

<ShippedItems>
     <Item>
          <Quantity>20</Quantity>
     </Item>
     <Item>
          <Quantity>24</Quantity>
     </Item>
</ShippedItems>

Within an xsl:for-each statement, XPath expressions are usually relative to the node selected by the xsl:for-each statement. For instance, in the preceding example Qty is relative to the current Item node /ns0:PurchaseOrder/Items/HighPriorityItems/Item:

  <xsl:for-each select="/ns0:PurchaseOrder/Items/HighPriorityItems/Item">
    <Item>
      <Quantity>
        <xsl:value-of select="Qty"/>
      </Quantity>
    </Item>
  </xsl:for-each>

Using absolute paths within the xsl:for-each statement can result in unintended results. For example, if were to use absolute path in the preceding example instead of relative path, the code looks as follows:

<ShippedItems>
 <xsl:for-each select="/ns0:PurchaseOrder/Items/HighPriorityItems/Item">
   <Item>
     <Quantity>
       <xsl:value-of 
              select="/ns0:PurchaseOrder/Items/HighPriorityItems/Item/Qty"/>
     </Quantity>
   </Item>
 </xsl:for-each>
</ShippedItems>

The resultant output document looks like the following:

<ShippedItems>
  <Item>
    <Quantity>20</Quantity>
  </Item>
  <Item>
    <Quantity>20</Quantity>       <!-- repeating incorrect value! -->
  </Item>
</ShippedItems>

The absolute path always selects the first Qty element in the Item node-set and you see a repeating value placed into each output Item element.

The XSLT Map Editor creates relative paths when mapping nodes under a for-each statement, if possible. It is recommended that you create the xsl:for-each statement before mapping the nodes that appear under the for-each. If you map nodes such as Quantity before adding the for-each, the editor shows a warning and attempts to refactor the absolute XPath expressions to relative path expressions when you map the node-set to the for-each.

Note:

  • Executing an auto map automatically inserts the xsl:for-each statement, where required.

  • Ensure that your design does not include infinite loops. Infinite loops can result in errors similar to the following during deployment and invocation of your application:

    ORAMED-04001:
    . . .
    oracle.tip.mediator.service.BaseActionHandler requestProcess 
    SEVERE: 
    failed reference BPELProcess1.bpelprocess1_client operation =  process