SharePoint XSL Counter

1k views Asked by At

So I've been banging my head against the wall for a while and am looking for some help. I'm trying to create a new itemstyle in sharepoint designer that basically checks each item in a task list and then tallies up the total number of Completed, In Progress, and Not Started statuses. The problem is to my knowledge, xsl doesn't have mutable variables. What I have so far is this:

<xsl:variable name="sChk">
        <xsl:value-of select="@Status"/>
</xsl:variable>
 <xsl:for-each select="@Status">
       <xsl:if test="$sChk = 'Completed' ">
           <!-- Add to Completed Counter -->
       </xsl:if>
       <xsl:if test="$sChk = 'In Progress' ">
               <!-- Add to In Progress Counter -->
       </xsl:if>
       <xsl:if test="$sChk = 'Not Started' ">
           <!-- Add to Not Started Counter -->
       </xsl:if>
        <br/>
    </xsl:for-each> 
    Out Of Loop:      
    Total Completed: <!-- Completed Value -->
    Total In Progress: <!-- In Progress Value -->
    Total Not Started: <!-- Not Started Value -->

Any and all help would be greatly appreciated, thanks!

EDIT: So I've also tried this recursive method as well but this isn't working either...

<xsl:param name="cCount" select="0"/>
<xsl:param name="ipCount" select="0"/>
<xsl:param name="nsCount" select="0"/>

<xsl:choose>
    <xsl:when test="$sChk = 'Completed'">
        <xsl:call-template name="PSRView2.0">
            <xsl:with-param name="cCount" select="$cCount +1"/>
            <xsl:with-param name="ipCount" select="$ipCount"/>
            <xsl:with-param name="nsCount" select="$nsCount"/>              
        </xsl:call-template>
    </xsl:when>
    <xsl:when test="$sChk = 'In Progress'">
        <xsl:call-template name="PSRView2.0">
            <xsl:with-param name="cCount" select="$cCount"/>
            <xsl:with-param name="ipCount" select="$ipCount +1"/>
            <xsl:with-param name="nsCount" select="$nsCount"/>              
        </xsl:call-template>
    </xsl:when>
    <xsl:when test="$sChk = 'Not Started'">
        <xsl:call-template name="PSRView2.0">
            <xsl:with-param name="cCount" select="$cCount"/>
            <xsl:with-param name="ipCount" select="$ipCount"/>
            <xsl:with-param name="nsCount" select="$nsCount +1"/>               
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$cCount"/>
        <xsl:value-of select="$ipCount"/>
        <xsl:value-of select="$nsCount"/>
    </xsl:otherwise>
</xsl:choose>  
1

There are 1 answers

6
Tim C On

You are correct in that in XSLT variables are immutable. What you need to use in your case those is the count function, which counts up all the items in a node-set. Something like this:

<xsl:variable name="completed" select="count(task[@Status='Completed'])" />
<xsl:variable name="inprogress" select="count(task[@Status='In Progress'])" />
<xsl:variable name="notstarted" select="count(task[@Status='Not Started'])" />
Total: <xsl:value-of select="$completed + $inprogress + $notstarted" />

Of course, you would need to replace 'task' with what ever element name you are using in your XSLT.

Without seeing your XML, it is hard to give a precise answer, but as an example, consider the following XML

<tasklist>
   <task status="Completed" />
   <task status="Completed" />
   <task status="In Progress" />
</tasklist>

Then the XSLT (to get totals only), would look like this

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="tasklist">
        <xsl:variable name="completed" select="count(task[@Status='Completed'])" />
        <xsl:variable name="inprogress" select="count(task[@Status='In Progress'])" />
        <xsl:variable name="notstarted" select="count(task[@Status='Not Started'])" />
        Total: <xsl:value-of select="$completed + $inprogress + $notstarted" />
    </xsl:template>
</xsl:stylesheet>

Notice how you need to be positioned on the parent element of all the individual 'task' elements here. As an alternative, you can do something like this...

<xsl:variable name="completed" select="count(//task[@Status='Completed'])" />

Which would count task elements wherever they are in the XML.

You could even do the following, if you really didn't know the element name, but were sure there were no other elements with a 'Status' attibute:

<xsl:variable name="completed" select="count(//*[@Status='Completed'])" />