I have a CQWP that returns all draft items in a single library, grouped by "Modified by." I would like to display a count of draft items next to each user's name.

I know how to edit Header.xsl, and have it displaying "0" for all users with the following xsl, which is obviously not getting the job done:

<xsl:value-of select="count(descendant::Row)"/>

I've tried several other variations on this. I'm sure it's a simple thing, but I'm running out of ideas to try.


EDIT: The desired result looks something like this:

Draft Topics by User
Firstname Lastname                6
Firstname Lastname                11
Firstname Lastname                16

and so on.

I've created a display template in header.xsl that does this, and the only problem is counting the items (I created an empty display template in itemstyle.xsl because I do not want the documents listed at this time).

So, I do not want to display any information about the documents at all, only a count, and I'd prefer to do this from header.xsl so I can output that count as shown above.

  • Did you try with this? <xsl:value-of select="position()" />
    – Marko Tica
    Commented Oct 1, 2014 at 21:41
  • I haven't, and am away from my PC at the moment, but won't that return each item's position rather than the total item count per user? Commented Oct 1, 2014 at 23:54
  • Well, I've confirmed that position() does not work as desired. It returns the value "1" for all users. Thanks for the thought, though! Commented Oct 2, 2014 at 13:07

3 Answers 3


I understand this is an older post but I was struggling with this same issue over the past couple days and have found a solution I thought I would share.

The trick is in understanding how the CQWP actually builds the XML structure. You can see this by editing the ContentQueryMain.xsl (found at /Style Library/XSL Style Sheets) by adding a new template that overrides all the others to view the raw XML data.

NOTE: As always, the best practice is to make a copy of the file and call that with your custom web part. Also, remember to change this back when done otherwise all your CQWP on the site will just show the XML rather than the formatted view!

<xsl:template match="/">
  <xmp><xsl:copy-of select="*"/></xmp>

Also you can enable automatic indenting on the template by finding the changing the line

<xsl:output method="xml" indent="no" />


<xsl:output method="xml" indent="yes" />

Save and check-in the file and then re-load the page with your CQWP. You should see a well formatted plain text outline of the data being queried

    <Row ListId="LIST_GUID_1" WebId="GUID" ID="1" parameter1="value1" parameter2="value1" Style="MyStyle" GroupStyle="MyGroup" _begincolum="True" _begingroup="True" />
    <Row ListId="LIST_GUID_1" WebId="GUID" ID="2" parameter1="value1" parameter2="value2" Style="MyStyle" GroupStyle="MyGroup" _begincolum="False" _begingroup="False" />
    <Row ListId="LIST_GUID_2" WebId="GUID" ID="3" parameter1="value2" parameter2="value3" Style="MyStyle" GroupStyle="MyGroup" _begincolum="False" _begingroup="True" />
    <Row ListId="LIST_GUID_2" WebId="GUID" ID="4" parameter1="value2" parameter2="value4" Style="MyStyle" GroupStyle="MyGroup" _begincolum="False" _begingroup="False" />

Looking at this we can see that the XML is structured without a break between items of different groups, which is why the basic count(.//Row) doesn't work. Instead what we need to do is walk back to the parent ("Rows") and get a count of "Row" that has been filtered to find only items like the one of the group we are currently counting. In this example, we are grouping by "parameter1" so we will want to get a count of items where parameter1 matches the value of parameter1 of the current item (which in the header will be the first item of a group). Here is the line of code in the Header.xml in the custom "MyStyle" template:

<xsl:value-of select="count(..//Row[@parameter1 = current()/@parameter1])"/>

And that's it! Put that where ever in your header template you want the count to appear and you should be all set!


Try this.

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />
<xsl:variable name="RowCount" select="count($Rows)" />
<xsl:variable name="IsEmpty" select="$RowCount = 0" />
<xsl:for-each select="$Rows">
  • $RowCount returns the total number of rows. I'm really not sure what the for-each is intended to accomplish. Maybe I didn't explain the problem clearly enough. I'll try editing the question. Commented Oct 2, 2014 at 13:38

I actually ended up using the list view app instead and applied some custom styling to it. Much simpler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.