Sep
Recently a client asked us if we could link the metadata for a SharePoint search result (which is the green text at the bottom of every search result) to bring the user to the document library / folder where the document is held.
At first this looked like quite a trivial task, edit the xslt to remove everything after the last forward slash:
Turning:
http://topLevelSite/Subsite/DocumentLibrary/folderone/foldertwo/document.doc
Into:
http://topLevelSite/Subsite/DocumentLibrary/folderone/foldertwo
This unfortunately proved not to be possible. This is because SharePoint uses xsl 1.0 which doesn’t have as much functionality as xsl 2.0.
The eventual solution involved:
1) Two templates:
• countTokens: a template used to count the number of a given symbol within a string, in this case /.
<!– Function to count the occurences of a string within another string –>
<xsl:template name="countTokens">
<xsl:param name="string" />
<xsl:param name="token" />
<xsl:param name="result" />
<xsl:choose>
<xsl:when test="contains($string, $token)">
<xsl:call-template name="countTokens">
<xsl:with-param name="string"
select="substring-after($string, $token)" />
<xsl:with-param name="token" select="$token"/>
<xsl:with-param name="result" select="$result + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$result" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
• Reverse: A template to reverse a string
<!– Function to reverse a given string –>
<xsl:template name="reverse">
<xsl:param name="input"/>
<xsl:variable name="len" select="string-length($input)"/>
<xsl:choose>
<!– Strings of length less than 2 are trivial to reverse –>
<xsl:when test="$len < 2">
<xsl:value-of select="$input"/>
</xsl:when>
<!– Strings of length 2 are also trivial to reverse –>
<xsl:when test="$len = 2">
<xsl:value-of select="substring($input,2,1)"/>
<xsl:value-of select="substring($input,1,1)"/>
</xsl:when>
<xsl:otherwise>
<!– Swap the recursive application of this template to
the first half and second half of input –>
<xsl:variable name="mid" select="floor($len div 2)"/>
<xsl:call-template name="reverse">
<xsl:with-param name="input"
select="substring($input,$mid+1,$mid+1)"/>
</xsl:call-template>
<xsl:call-template name="reverse">
<xsl:with-param name="input"
select="substring($input,1,$mid)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
2) Changes to span class="srch-URL", which resides within p class="srch-Metadata"
<span class="srch-URL">
<!– Get number of slashes in URL –>
<xsl:variable name="numberofslashes">
<xsl:call-template name="countTokens">
<xsl:with-param name="string" select="$url" />
<xsl:with-param name="token" select="string(’/')" />
<xsl:with-param name="result" select="0" />
</xsl:call-template>
</xsl:variable>
<!– Reverse the URL –>
<xsl:variable name="reversedurl">
<xsl:call-template name="reverse">
<xsl:with-param name="input" select="$url" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="newurl">
<xsl:choose>
<!– If it contains 3+ slashes, we can remove what’s left after the last one –>
<xsl:when test="number($numberofslashes) > 3">
<xsl:call-template name="reverse">
<xsl:with-param name="input" select="substring-after($reversedurl, ‘/’)" />
</xsl:call-template>
</xsl:when>
<!– Otherwise just reverse it back –>
<xsl:otherwise>
<xsl:call-template name="reverse">
<xsl:with-param name="input" select="$reversedurl" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<a href="{$newurl}" id="{concat(’CSR_U_’,$id)}" title="{$url}" dir="ltr">
<xsl:choose>
<xsl:when test="hithighlightedproperties/HHUrl[. != '']">
<xsl:call-template name="HitHighlighting">
<xsl:with-param name="hh" select="hithighlightedproperties/HHUrl" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="url"/>
</xsl:otherwise>
</xsl:choose>
</a>
</span>
This code works by reversing the string original string to give the string backwards:
http://topLevelSite/Subsite/DocumentLibrary/folderone/foldertwo/document.doc
Would become:
cod.tnemucod/owtredlof/enoredlof/yrarbiLtnemucoD/etisbuS/etiSleveLpot//:ptth
If there are more than 3 forward slashes in the string, we take the substring after the first slash of the reversed string:
owtredlof/enoredlof/yrarbiLtnemucoD/etisbuS/etiSleveLpot//:ptth
and then reverse it back:
http://topLevelSite/Subsite/DocumentLibrary/folderone/foldertwo
if there are less than 3 slashes:
etiSleveLpot//:ptth
Just reverse the string back:
Looks like we’ll be able to develop for the iPhone or iTouch using C#. The development environment isn’t Visual Studio though.