2

I'm looking to use the Content Query web part in Sharepoint 2010 to return items from a list. What I'm trying to do is return a list of categories available from all the items available. This is bringing back duplicates in the list. Does anyone know if there is a way in the xsl style sheets to remove/hide these duplicates? Or possibly a setting on the web part I've overlooked.

Thanks in advance

2 Answers 2

2

To remove duplicates in CQWP using Xslt based approach the grouping capabilities could be used.

Input data

Suppose we have a list with the following customers

Customer A
Customer A
Customer B
Customer C
Customer C
Customer C
Customer D

Let's see how CQWP could be configured to display results without duplicates

Enable grouping

First step to enable grouping by customer name (title column) as shown on picture below

enter image description here

The CQWP results should look like this

enter image description here

Customize the results

Now our goal to transform results in such a way that only marked items will be displayed

Save a copy of ContentQueryMain.xsl and modify it as described below

First, create the template for rendering grouped item

<xsl:template name="OuterTemplate.CallGroupItem">
      <xsl:param name="CurPosition" />
      <xsl:value-of disable-output-escaping="yes" select="$BeginListItem" />
      <xsl:apply-templates select="." mode="itemstyle">
              <xsl:with-param name="CurPos" select="$CurPosition" />
         </xsl:apply-templates>
      <xsl:value-of disable-output-escaping="yes" select="$BeginList" />
    </xsl:template>  

and then modify OuterTemplate.Body to render grouped item

<xsl:template name="OuterTemplate.Body">
      <xsl:param name="Rows" />
      <xsl:param name="FirstRow" />
      <xsl:param name="LastRow" />
      <xsl:variable name="BeginColumn1" select="string('&lt;ul class=&quot;dfwp-column dfwp-list&quot; style=&quot;width:')" />
      <xsl:variable name="BeginColumn2" select="string('%&quot; &gt;')" />
      <xsl:variable name="BeginColumn" select="concat($BeginColumn1, $cbq_columnwidth, $BeginColumn2)" />
      <xsl:variable name="EndColumn" select="string('&lt;/ul&gt;')" />
      <xsl:for-each select="$Rows">
            <xsl:variable name="CurPosition" select="position()" />
            <xsl:if test="($CurPosition &gt;= $FirstRow and $CurPosition &lt;= $LastRow)">
                <xsl:variable name="StartNewGroup" select="@__begingroup = 'True'" />
                <xsl:variable name="StartNewColumn" select="@__begincolumn = 'True'" />
                <xsl:choose>
                    <xsl:when test="$cbq_isgrouping != 'True'">
                        <xsl:if test="$CurPosition = $FirstRow">
                            <xsl:value-of disable-output-escaping="yes" select="$BeginColumn" />
                        </xsl:if>
                    </xsl:when>
                    <xsl:when test="$StartNewGroup and $StartNewColumn">
                        <xsl:choose>
                            <xsl:when test="$CurPosition = $FirstRow">
                                <xsl:value-of disable-output-escaping="yes" select="$BeginColumn" />
                                <!--xsl:call-template name="OuterTemplate.CallHeaderTemplate"/-->
                                <xsl:call-template name="OuterTemplate.CallGroupItem">
                                     <xsl:with-param name="CurPosition" select="$CurPosition" />
                                </xsl:call-template>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
                                <xsl:value-of disable-output-escaping="yes" select="concat($EndColumn, $BeginColumn)" />
                                <!--xsl:call-template name="OuterTemplate.CallHeaderTemplate"/-->
                                <xsl:call-template name="OuterTemplate.CallGroupItem">
                                    <xsl:with-param name="CurPosition" select="$CurPosition" />
                                </xsl:call-template>
                             </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:when test="$StartNewGroup">
                        <xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
                        <!--xsl:call-template name="OuterTemplate.CallHeaderTemplate"/-->
                        <xsl:call-template name="OuterTemplate.CallGroupItem">
                           <xsl:with-param name="CurPosition" select="$CurPosition" />
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:when test="$StartNewColumn">
                        <xsl:choose>
                            <xsl:when test="$CurPosition = $FirstRow">
                                <xsl:value-of disable-output-escaping="yes" select="$BeginColumn" />
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of disable-output-escaping="yes" select="concat($EndColumn, $BeginColumn)" />
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise>
                    </xsl:otherwise>
                </xsl:choose>
                <!--xsl:call-template name="OuterTemplate.CallItemTemplate">
                    <xsl:with-param name="CurPosition" select="$CurPosition" />
                </xsl:call-template-->
                <xsl:if test="$CurPosition = $LastRow">
                  <xsl:if test="$cbq_isgrouping = 'True'">
                    <xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
                  </xsl:if>
                  <xsl:value-of disable-output-escaping="yes" select="$EndColumn" />
                </xsl:if>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

You could find the source code here

The last step is to replace Main Xsl with custom one (for example, export web part and specify Main Xsl property)

For more information about customizing CQWP please follow this article.

Result

enter image description here

1
  • This was exactly what I was looking for, thank you so much!
    – William
    Commented Apr 15, 2013 at 8:02
1

Have you read this blog post from Waldek?

It is about generating a Tag cloud from categories. It seems very similar to your scenario.

Especially this quote:

We can retrieve all the different categories using one single XPath function (→ means a forced line break. In the real code it would be in one line):

<xsl:variable name="TagsArray" 
select="Row[not(@Category=preceding-sibling::Row/@Category)]/@Category"/>

Although it seems pretty complex it works very simple: for each node the value of the Category attribute is being compared the value of the Category attribute of the previous sibling node. Because the function is included in a not clause we will get all the distinct categories.

My tip is to read the blogpost and try modifying it to your specific scenario!

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.