A fast way to do sum calculation in XSLT

In general, SharePoint developers avoid XSLT because is limited, this also being the one of the reasons SharePoint 2013 has started to adopt more and more JavaScript. But this doesn’t mean is dead. It is still very powerful being extended with ddwrt functions. I remember one of the challenges in XSLT was to calculate the sum of one column, as starting with SharePoint 2010 numbers output contains commas. It took a while for me also to figure out how I can do this in fast and reliable way, but it turned out was not so complicated as I thought.

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
	<xsl:template match="/">
		<!-- Create a variable TotalAmount and set it to zero -->
		<xsl:value-of select="ddwrt:SetVar('TotalAmount', 0)" />
		<!-- Iterate through the rows and increase TotalAmount with current amount (commas are removed to allow number conversion) -->
		<xsl:for-each select="/dsQueryResponse/Rows/Row">
			<xsl:value-of select="ddwrt:SetVar('TotalAmount', number(translate(@Amount,',','')))" />
		</xsl:for-each>
		<!-- Output the result -->
		<xsl:value-of select="ddwrt:GetVar('TotalAmount')" disable-output-escaping="yes" />
	</xsl:template>
</xsl:stylesheet>

SetVar function is allowing me to create and modify a variable. So with each row included in for-each iteration, the total amount is increased and, at the end of the iteration, calling GetVar function will output the result. This should be fast enough and avoids other operations outside for-each tag. In general, I used at least one for-each declaration per data form web part as the purpose of it is anyhow to show data.

GetVar and SetVar functions are opening a whole word for more complex calculation. Using them I was able to create complicated reports based on SharePoint lists.

Advertisements

ddwrt namespace – extension functions detailed

Webparts like DataFormWebPart are still useful and powerful webparts, even if Microsoft is trying to push the SharePoint development to client side by introducing JSLink. One of the reason is because XSLT is extended to some functions coming from ddwrt namespace. These can be found and documented on this link. I am also extended the page by presenting how actually these functions can be used in your XSLT code.

Function Usage Output
GetFileExtension <xsl:value-of select=”ddwrt:GetFileExtension(‘excelfile.doc’)” /> doc
GetVar and SetVar <xsl:variable name=”MyVar” />
<xsl:value-of select=”ddwrt:SetVar(‘MyVar’,’My Value’)” />
<xsl:value-of select=”ddwrt:GetVar(‘MyVar’)” />
My Value
IsPrivilegedUser <xsl:if test=”ddwrt:IsPrivilegedUser() = false”>Not admin</xsl:if> Not admin
Limit <xsl:value-of select=”ddwrt:Limit(‘Long text’, 4,’…’)” /> Long…
Counter <xsl:value-of select=”ddwrt:Counter()” />,<xsl:value-of select=”ddwrt:Counter()” />,<xsl:value-of select=”ddwrt:Counter()” /> 1,2,3
FormatDate <xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,1)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,3)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,4)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,5)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,7)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,12)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,13)” /><br />
<xsl:value-of select=”ddwrt:FormatDate(‘2014-08-20T08:00:00Z’,1033,15)” />
8/20/2014
Wednesday, August 20, 2014
1:00 AM
8/20/2014 1:00 AM
Wednesday, August 20, 2014 1:00 AM
1:00:00 AM
8/20/2014 1:00:00 AM
Wednesday, August 20, 2014 1:00:00 AM
IfNew <xsl:if test=”ddwrt:IfNew(‘2014-08-20T08:00:00Z’) = ‘true'”>Recent</xsl:if>
ListProperty  <xsl:value-of select=”ddwrt:ListProperty(‘itemCount’)” />
<xsl:value-of select=”ddwrt:ListProperty(‘title’)” />
UserLookup <xsl:value-of select=”ddwrt:UserLookup($UserID,’ID’)” />
<xsl:value-of select=”ddwrt:UserLookup($UserID,’Email’)” />
<xsl:value-of select=”ddwrt:UserLookup($UserID,’Login’)” />

I consider these functions very valuable. I personally used with some success GetVar and SetVar for making more complicated calculation in the webpart without being forced to call XSLT templates recursively. So, if you still develop in XSLT, which is not a bad idea, you can look if you can use these functions. . If you can see this attribute, xmlns:ddwrt=http://schemas.microsoft.com/WebParts/v2/DataView/runtime, this means you can use them.