Oracle SOA Suite Online Training

Interested in learning Oracle SOA Suite 12c?
Learn from the author of this blog!
A complete and comprehensive course on the #1 platform on SOA - Oracle SOA Suite

Click here to find the complete course details
Click here to check the first session on Oracle SOA Suite 12c

================================================================================================

Grouping XML elelments using XSLT - xsl:for-each-group

This is an informal post on XSLT for-each-group which is very powerful function to group xml elements based on some criteria.

For Ex, you may want to convert a flat structure, typically returned by DB into an xml which is, say department wise. for-each-group is what you want

This sample is to convert a flat structure into a projectOwner wise grouping

Input

<MailPayload>                              
    <ActivityPayload>                              
        <ActivityId>101</ActivityId>      
        <ActivityName>T1</ActivityName>      
        <ActivityOwner>Act1Owner</ActivityOwner>      
        <ProjectId>1001</ProjectId>          
        <ProjectName>Prj1</ProjectName>      
        <ProjectOwner>PrjOwner</ProjectOwner>      
        <ApprovalStatus>some desc 1</ApprovalStatus>
        <Comments>comments1</Comments>
    </ActivityPayload>                              
    <ActivityPayload>                              
        <ActivityId>102</ActivityId>      
        <ActivityName>T2</ActivityName>      
        <ActivityOwner>Act2Owner</ActivityOwner>      
        <ProjectId>1002</ProjectId>          
        <ProjectName>Prj2</ProjectName>      
        <ProjectOwner>PrjOwner</ProjectOwner>      
        <ApprovalStatus>some desc 2</ApprovalStatus>
        <Comments>comments2</Comments>
    </ActivityPayload>                              
</MailPayload>

Ouput Format required

<?xml version="1.0" encoding="UTF-8"?>
<MailPayload>
<ProjectOwnerWise>
<ProjectOwner>PrjOwner</ProjectOwner>
<Activities>
<IndActivity>
<ActivityId>101</ActivityId>
<ActivityName>T1</ActivityName>
<ProjectId>1001</ProjectId>
<ProjectName>Prj1</ProjectName>
<Comments>comments1</Comments>
</IndActivity>
<IndActivity>
<ActivityId>102</ActivityId>
<ActivityName>T2</ActivityName>
<ProjectId>1002</ProjectId>
<ProjectName>Prj2</ProjectName>
<Comments>comments2</Comments>
</IndActivity>
</Activities>
</ProjectOwnerWise>
<ProjectOwnerWise>
<ProjectOwner>PrjOwner2</ProjectOwner>
<Activities>
<IndActivity>
<ActivityId>103</ActivityId>
<ActivityName>T3</ActivityName>
<ProjectId>1002</ProjectId>
<ProjectName>Prj3</ProjectName>
<Comments>comments2</Comments>
</IndActivity>
</Activities>
</ProjectOwnerWise>
</MailPayload>

XSLT
-------

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
   <MailPayload>
<xsl:for-each-group select="/MailPayload/ActivityPayload" group-by="ProjectOwner">
   <ProjectOwnerWise>
<ProjectOwner>
 <xsl:value-of select="current-grouping-key()"/>
</ProjectOwner>
<Activities>
 <xsl:for-each select="current-group()">
  <IndActivity>
<xsl:copy-of select="ActivityId|ActivityName|ProjectId|ProjectName|ReviewerDecision|Comments"/>
  </IndActivity>
 </xsl:for-each>
</Activities>
</ProjectOwnerWise>
</xsl:for-each-group>
   </MailPayload>
  </xsl:template>
</xsl:stylesheet>

for-each-group groups the entire xml as per the group-by value defined and loads in memory
ex : <xsl:for-each-group select="/MailPayload/ActivityPayload" group-by="ProjectOwner">  -- ProjectOwner here

current-grouping-key() gives the values of all ProjectOwner
current-group() lists all the tags defined in a particular set


No comments:

Post a Comment