Tuesday, October 26, 2010

XSLT 2.0 Grouping & Sorting in 11g BPEL

I had a requirement recently where I had to split my incoming XML file(read from a database) based on a particular field and send the split sections to another BPEL process for further processing.

Here is how the Input xml looked like


 
  arr1
  ...
  ...
  
  
  arr2
  ...
  ...
  
  
  arr1
  ...
  ...
  
  
  arr2
  ...
  ...
  


Desired Output looks like this.



  
  arr1
  ...
  ...
  
  
  arr1
  ...
  ...
  


  
  arr2
  ...
  ...
  
  
  arr2
  ...
  ...
  



As can be seen above, the idea was to split the Input xml based on arr_id field into different collections and each collection having data for a particular arr_id. Once this is done, all I had to do is run a loop in my BPEL and for each collection send the data to the 2nd BPEL process.

I decided to use XSLT Grouping and Sorting feature to accomplish this task. If we are using XSLT 1.0 there is a particular way to do this using xsl:key which has been explained well in http://www.jenitennison.com/xslt/grouping/muenchian.html . However this can be done easily in XSLT 2.0 using xsl:for-each-group.

Below is the XSL file which does this task for us,

<xsl:stylesheet version="2.0" xmlns:ns1="http://xmlns.oracle.com/pcbpel/adapter/db/Select_Arrid" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="/">
  <ns1:root>
    <xsl:for-each-group select="*/ns1:Select_Arrid" group-by="ns1:Arr_id">
        <xsl:sort select="current-grouping-key()">
        <ns1:select_arrid_collection>
           <xsl:copy-of select="current-group()">
                <xsl:apply-templates/>
          </xsl:copy-of> 
        </ns1:select_arrid_collection>
      </xsl:sort>
    </xsl:for-each-group>
   </ns1:root>
 </xsl:template>
</xsl:stylesheet>

Make sure the version of XSL is 2.0 for using the xsl:for-each-group construct. Now the xsl can be used in any transform activity and will give us the desired output. Hope this helps someone having similar XSLT grouping requirement in BPEL.

3 comments:

  1. Hi,
    I have same requirement with the Grouping. If I use the XSLT 2.0 file directly using the Mediator Transformation; I am getting error.
    Can you show us how to use the xsl file in SOA suite Components

    Sushil

    ReplyDelete
  2. What error are you getting while using it in Mediator transformation ?

    ReplyDelete
  3. Hi sahu,

    I have same requirement to convert the input XMl from Database adapter data.
    I will get the collection object from DB adapter.But where Do I apply xsl snippet that you gave(that is related for-each-group snippet).After I get the input from receive activity,Where Do i apply that snippet.How Do I map after applying that snippet?
    How do I loop through each collection object?
    Can You give some explanation as I am in very very urgent Situation to resolve the task?

    ReplyDelete