I am using a linked datasource in MOSS to create a dynamic table of contents page based on a metadata associated with files in a document library. The library contains multilookup columns for the following: Audience, Category, Subcategory. Users get to the toc page by clicking from another page to pass the Audience in the query string. The toc page will filter the categories based on Audience.
The categories are displayed using the categories list and then the subcategories are matched to the respective category based on the join.
The original problem was that these were delimited strings. I broke the strings out using a recursive template. Now my problem is removing duplicates. I am able to remove the subcategory if it matches up exactly, but because of the multiple values this almost never happens. Is there a way to do this using xslt or will I need to look into some sort of jquery.
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" 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:output method="html" indent="no"/>
<xsl:decimal-format NaN=""/>
<xsl:param name="dvt_apos">'</xsl:param>
<xsl:param name="Audience" />
<xsl:param name="HelpURL" />
<xsl:variable name="dvt_1_automode">0</xsl:variable>
<xsl:template match="/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
<xsl:call-template name="CategoryList"/>
</xsl:template>
<xsl:template name="CategoryList">
<xsl:variable name="dvt_StyleName">2ColCma</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Categories/Rows/Row" />
<link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/controls.css"/>
<table border="0" width="100%">
<tr>
<xsl:call-template name="CategoryList.body">
<xsl:with-param name="Rows" select="$Rows" />
</xsl:call-template>
</tr>
</table>
</xsl:template>
<xsl:template name="CategoryList.body">
<xsl:param name="Rows" />
<xsl:for-each select="$Rows">
<xsl:sort select="../../../Rows/Row/@Title" order="ascending" />
<xsl:call-template name="CategoryList.rowview" />
</xsl:for-each>
</xsl:template>
<xsl:template name="CategoryList.rowview">
<xsl:variable name="ParentCategory" select="@Title" />
<xsl:variable name="DocumentRows" select="../../../Documents/Rows/Row[contains(@Category, $ParentCategory) and contains(@Audience, $Audience)]" />
<xsl:variable name="RowCount" select="count($DocumentRows)" />
<xsl:variable name="dvt_IsEmpty" select="$RowCount = 0" />
<xsl:if test="$RowCount > 0">
<td valign="top" width="50%">
<table border="0" cellspacing="0" width="100%">
<tr class="ms-WPHeader" >
<td width="75%" class="ms-standardheader ms-WPTitle">
<xsl:value-of select="@Title" /></td>
</tr>
<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">
<tr>
<td colspan="99" class="ms-vb">
<span ddwrt:amkeyfield="" ddwrt:amkeyvalue="string($XPath)" ddwrt:ammode="view" />
</td>
</tr>
</xsl:if>
<tr>
<td width="75%" class="ms-vb">
<xsl:call-template name="Documents" />
</td>
</tr>
</table>
</td>
<xsl:if test="position() mod 2 = 0" ddwrt:cf_ignore="1">
<xsl:text disable-output-escaping="yes"></tr></xsl:text>
<xsl:if test="position() != last()" ddwrt:cf_ignore="1">
<xsl:text disable-output-escaping="yes"><tr></xsl:text>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:variable name="dvt_2_automode">0</xsl:variable>
<xsl:template name="Documents">
<xsl:variable name="dvt_StyleName">Table</xsl:variable>
<xsl:variable name="dvt_ParentRow" select="current()" />
<xsl:variable name="Rows" select="../../../Documents/Rows/Row[contains(@Category, $dvt_ParentRow/@Title) and contains(@Audience, $Audience)]" />
<xsl:variable name="dvt_RowCount" select="count($Rows)" />
<xsl:variable name="dvt_IsEmpty" select="$dvt_RowCount = 0" />
<xsl:choose>
<xsl:when test="$dvt_IsEmpty">
<xsl:call-template name="dvt_1.empty" />
</xsl:when>
<xsl:otherwise>
<table border="0" width="100%" cellpadding="2" cellspacing="0">
<xsl:call-template name="Documents.body">
<xsl:with-param name="Rows" select="$Rows" />
<xsl:with-param name="dvt_ParentRow" select="$dvt_ParentRow" />
</xsl:call-template>
</table>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="Documents.body">
<xsl:param name="Rows" />
<xsl:param name="dvt_ParentRow" />
<xsl:for-each select="$Rows">
<xsl:sort select="@Subcategory" />
<xsl:call-template name="Documents.rowview" >
<xsl:with-param name="dvt_ParentRow" select="$dvt_ParentRow/@Title" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="Documents.rowview">
<xsl:param name="dvt_ParentRow" />
<xsl:variable name="SubcatRow" select="ddwrt:NameChanged(string(@Subcategory), 0)" />
<xsl:if test="string-length($SubcatRow)">
<tr>
<td class="ms-vb">
<xsl:call-template name="subcategoryLinks">
<xsl:with-param name="subcategory" select="@Subcategory" />
<xsl:with-param name="SingleCategory" select="$dvt_ParentRow" />
</xsl:call-template>
</td>
</tr>
</xsl:if>
</xsl:template>
<!--Template used to determine subcategories -->
<xsl:template name="subcategoryLinks">
<xsl:param name="SingleCategory" />
<xsl:param name="subcategory" />
<xsl:variable name="firstSubcat" select="substring-before($subcategory, ';')" />
<xsl:variable name="remainSubcat" select="substring-after($subcategory, ';')" />
<xsl:choose>
<!--Tests to see if there are more than 1 subcategory-->
<xsl:when test="not(contains(@Subcategory, ';'))">
<div id="subLink" class="bullet" style="font-size:10pt;">
<a href="{$HelpURL}{$Audience}&Category={$SingleCategory}&SubCategory={@Subcategory}"><xsl:value-of select="@Subcategory" /></a>
</div>
</xsl:when>
<!--Runs if more than 1 subcategory-->
<xsl:otherwise>
<!--Creates subcategory row-->
<div id="subLink" class="bullet" style="font-size:10pt;">
<a href="{$HelpURL}{$Audience}&Category={$SingleCategory}&SubCategory={$firstSubcat}">
<xsl:value-of select="$firstSubcat" /> </a>
</div>
<xsl:choose>
<!--Tests to see if more than 1 subcategory remains, if so it will rerun the template-->
<xsl:when test="contains($remainSubcat, ';')" >
<xsl:call-template name="subcategoryLinks">
<xsl:with-param name="subcategory" select="$remainSubcat" />
<xsl:with-param name="SingleCategory" select="$SingleCategory" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<div id="subLink" class="bullet" style="font-size:10pt;">
<a href="{$HelpURL}{$Audience}&Category={$SingleCategory}&SubCategory={$remainSubcat}"><xsl:value-of select="$remainSubcat" /></a>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="dvt_1.empty">
<xsl:variable name="dvt_ViewEmptyText">No items.</xsl:variable>
<table border="0" width="100%">
<tr>
<td class="ms-vb" style="height: 17px">
<xsl:value-of select="$dvt_ViewEmptyText" />
</td>
</tr>
</table>
</xsl:template>