XSL - Removing the filename from the path string

MrFidge picture MrFidge · Oct 8, 2010 · Viewed 8.2k times · Source

I've got a SharePoint problem which I need some help with. I'm creating some custom ItemStyles to format the output of a Content Query Webpart (CQWP) but I need to insert a "view all" button into the output.

View all needs to point to: http://www.site.com/subsite/doclibrary1/Forms/AllItems.aspx

All the individual files in the document library have the link of: http://www.site.com/subsite/doclibrary1/FileName.doc

So what I need is some XSL functions to strip FileName.doc from the end of the string.

I've tried using substring-before($variable, '.') to get rid of the .doc, but I then need to find a way to use substring-after to search for the LAST forward slash in the series and truncate the orphaned filename.

Using @Mads Hansen's post, this is the code which resolved the problem:

Template in ItemStyle.xsl

<xsl:template name="ImpDocs" match="Row[@Style='ImpDocs']" mode="itemstyle">
    <xsl:variable name="SafeLinkUrl">
        <xsl:call-template name="OuterTemplate.GetSafeLink">
            <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="ViewAllLink">
        <xsl:call-template name="OuterTemplate.getCleanURL">
            <xsl:with-param name="path" select="@LinkUrl"/>
        </xsl:call-template>
    </xsl:variable>
    <div class="DocViewAll">
        <a href="{$ViewAllLink}Forms/AllItems.aspx" title="View all">View All</a>
        <!--Any other code you need for your custom ItemStyle here-->
    </div>
</xsl:template>

Template in ContentQueryMain.xsl

<xsl:template name="OuterTemplate.getCleanURL">
    <xsl:param name="path" />
    <xsl:choose>
        <xsl:when test="contains($path,'/')">
            <xsl:value-of select="substring-before($path,'/')" />
            <xsl:text>/</xsl:text>
            <xsl:call-template name="OuterTemplate.getCleanURL">
                <xsl:with-param name="path" select="substring-after($path,'/')" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise />
    </xsl:choose>
</xsl:template>

Answer

Mads Hansen picture Mads Hansen · Oct 8, 2010

Executing this stylesheet produces: http://www.site.com/subsite/doclibrary1/

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
<xsl:template match="/">

    <xsl:call-template name="getURL">
        <xsl:with-param name="path">http://www.site.com/subsite/doclibrary1/FileName.doc</xsl:with-param>
    </xsl:call-template>
</xsl:template>

    <xsl:template name="getURL">
        <xsl:param name="path" />
        <xsl:choose>
            <xsl:when test="contains($path,'/')">
                <xsl:value-of select="substring-before($path,'/')" />
                <xsl:text>/</xsl:text>
                <xsl:call-template name="getURL">
                    <xsl:with-param name="path" select="substring-after($path,'/')" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise />
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

The getURL template makes a recursive call to itself when there are "/" characters in the string. While there are still "/" characters, it spits out the values before the slash, and then invokes itself. When it reaches the last one, it stops.