PANVEGA’s Blog

DotNet Development, SharePoint Customizing, Silverlight, MS Infrastructure and other tips and tricks

Easy Grouping in XSLT 1.0

Posted by PANVEGA on June 10, 2009

I was asked to implement a grouping by TEAM with all the employees regarding to the Team Name into a SharePoint People Results Webpart. Here I am gonna show you a very nice aproach how to realize this custom request.

I read in so many posts how to create a proper grouping results in XSLT 1.0. XSLT 2.0 makes grouping even easier than Steve did. The XSLT 2.0 xsl:for-each-group instruction iterates across a series of groups, with the criteria for grouping specified by its attributes.  While XSLT 1.0 lets you sort elements, it still forces you to jump through several hoops to do anything extra with the groups that result from the sort.

Here is a snipped of the XML file:

<?xml version="1.0" ?>
<All_Results>
 <Result>
  <Team>BI</Team>
  <PreferedName>Alex</PreferedName>
  <Function>1</Function> 
 </Result> 
<Result>
  <Team>BI</Team>
  <PreferedName>Max</PreferedName>
  <Function>3</Function>
 </Result> 
<Result>
  <Team>BDEV</Team>
  <PreferedName>Moritz</PreferedName>
  <Function>1</Function>
 </Result>
</All_Results>

XSLT 2.0 example:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 version="2.0">
 <xsl:output method="text"/>
 <xsl:template match="Result">

 <xsl:for-each-group select="file" group-by="@team">
 <xsl:value-of select="current-grouping-key()"/>
 <xsl:text>
 </xsl:text>
 </xsl:for-each-group>

 </xsl:template>
</xsl:stylesheet>

XSLT 1.0 Example

First, you must define the keys required to group the <Result> elements. You will need one for the team, and one for the preferredname

<xsl:key name="groupby" match="Result" use="team"/>
<xsl:key name="employeeName" match="Result" use="preferredname" />

<xsl:template  match="All_Results">

<!--Select the first element of each group of elements for each unique TeamID-->
<xsl:for-each select="Result[generate-id(.) =generate-id(key('groupby', team)[1])]" >
<xsl:sort select="team" order="ascending" />
<xsl:variable name="TeamID"><xsl:value-of select="team" /></xsl:variable>

<!-- Select all the Employees belonging to the Team -->
<xsl:variable name="lstEmployee" select="//Result[team=$TeamID]" />
 <tr > <td colspan="4" >Team: <xsl:value-of select="$lstEmployee[1]/team" /></td></tr> 

<!--The <Result> elements in this list must now be grouped by preferedname. This is similar  to grouping by Team, except that in this
case you only need to select elements in the list  contained in the variable;  you do not need to select elements from the entire result set.-->

<tr style="height:6px;"><td colspan="4"></td></tr>
<xsl:for-each select="$lstEmployee[generate-id(.) = generate-id(key('employeeName', preferredname)[1])]">
<xsl:sort select="preferredname" order="ascending" />
 <xsl:variable name="lngEmployeeID" select="preferredname" />

 <a href="{$url}" id="{concat('CSR_',$id)}" target="_blank">
 <xsl:value-of select="$lstEmployee[preferredname=$lngEmployeeID]/preferredname" />
 <xsl:if test='string-length(jobtitle) &gt; 0'>
 <xsl:value-of select="concat(', ',jobtitle)" />
 </xsl:if>
 </a>

</xsl:for-each>
</xsl:template>

Of course, you can call a template instead of the for-each.

<!-- Show details for Employees in Team -->
<xsl:call-template name="EmployeesInTeam">
 <xsl:with-param name="lstEmployee" select="$lstEmployee" />
</xsl:call-template>

More Informations:

http://www.jenitennison.com/xslt/grouping

http://www.w3.org/TR/xslt20/

http://www.stylusstudio.com/xsllist/200504/post00580.html

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: