Tuesday, October 19, 2010

Looping over each nodes in Oracle BPEL

This is an example how to use WHILE loop in Oracle BPEL Process Manager 11g.



This example will be based on the JDEPurchaseOrders.xsd schema and the JDEPurchaseOrders.xml sample data.

Step 1, create another XSD to map your temporary data at for each node. Let's call it JDEPurchaseOrder.xsd.

Step 2, create variables based on the message type that contains this collection, and 2 counters, Variable_LoopRunningIndex for the running index, and Variable_LoopCounter for the length of the collection.As shown below:

    <variable name="Variable_LoopRunningIndex" type="xsd:integer"/>
    <variable name="Variable_LoopCounter" type="xsd:integer"/>
    <variable name="Variable_tempJDEPurchaseOrder" element="ns3:HEADER"/>

Step 3, initialise variables for looping.
    <assign name="Initialise_WhileLoop">
      <copy>
        <from expression="number(1)"/>
        <to variable="Variable_LoopRunningIndex"/>
      </copy>
      <copy>
        <from expression="ora:countNodes('Receive_JDEFlatfile_Read_InputVariable','body','/ns3:JDEPurchaseOrder/ns3:HEADER/ns3:ID') + 1"/>
        <to variable="Variable_LoopCounter"/>
      </copy>
    </assign> 
Step 4, implement BPEL while activity to loop over each node
    <while name="For_Each_Header_Record"
           condition="bpws:getVariableData('Variable_LoopRunningIndex') &lt; bpws:getVariableData('Variable_LoopCounter')">
      <bpelx:annotation>
        <bpelx:general>
          <bpelx:property name="userLabel">For_Each_Header_Record</bpelx:property>
        </bpelx:general>
      </bpelx:annotation>
      <sequence name="Split_Purchase_Order">
        <scope name="Scope_1">
        <!-- Declare scope variables -->
          <variables>
            <variable name="Variable_selector" type="xsd:string"/>
            <variable name="Variable_tempJDEPurchaseOrder" element="ns3:HEADER"/>
          </variables>
          <sequence name="Sequence_1">
          <!-- Map current node into temp struct -->
            <assign name="Create_tempJDEPurchaseOrder">
              <copy>
                <from expression="concat(&quot;/ns3:JDEPurchaseOrder/ns3:HEADER[&quot;, string(bpws:getVariableData('Variable_LoopRunningIndex')),&quot;]&quot;)"/>
                <to variable="Variable_selector"/>
              </copy>
              <copy>
                <from expression="bpws:getVariableData('Receive_JDEFlatfile_Read_InputVariable','body', bpws:getVariableData('Variable_selector'))"/>
                <to variable="Variable_tempJDEPurchaseOrder"/>
              </copy>
            </assign>
            <!-- Transform temp struct required output -->
            <assign name="XForm_tempJDEPurchaseOrder_to_EDIFACT">
              <bpelx:annotation>
                <bpelx:pattern>transformation</bpelx:pattern>
              </bpelx:annotation>
              <copy>
                <from expression="ora:processXSLT('xsl/XForm_tmpJDEPurchaseOrder2EDIFACT.xsl',bpws:getVariableData('Variable_tempJDEPurchaseOrder'))"/>
                <to variable="SendPurchaseOrder_send_InputVariable"
                    part="body"/>
              </copy>
            </assign>
            <!-- Send output to B2B to dispatch -->
            <invoke name="SendPurchaseOrder"
                    inputVariable="SendPurchaseOrder_send_InputVariable"
                    partnerLink="DispatchPurchaseOrder"
                    portType="ns2:B2B_send_ptt" operation="send">
              <bpelx:inputProperty name="b2b.documentProtocolVersion"
                                   variable="Variable_documentProtocolVersion"/>
              <bpelx:inputProperty name="b2b.documentTypeName"
                                   variable="Variable_documentTypeName"/>
              <bpelx:inputProperty name="b2b.toTradingPartnerId"
                                   variable="Variable_toTradingPartnerId"/>
            </invoke>
          </sequence>
        </scope>
        <!-- Increment the index and repeat next node -->
        <assign name="Increment_LoopRunningIndex">
          <copy>
            <from expression="bpws:getVariableData('Variable_LoopRunningIndex') + 1"/>
            <to variable="Variable_LoopRunningIndex"/>
          </copy>
        </assign>
      </sequence>
    </while>