xsl-list
[Top] [All Lists]

[xsl] Unexpected result from <a href="...">...</a> in some cases

2008-08-19 15:19:54
I've scanned through the archives, but haven't yet found a solution for this particular problem. First post to the list, so be merciful. :-)

I've created a recursive template (printRecursivePath) to process a directory path and build up a string of links from the right side so as to correctly increase the number of "../" elements for parent link. (I tried using the tokenize() function, but it's apparently not supported in my XSLT, and I'd like to keep this portable and minimize dependencies.) The output is in HTML for a standard webpage.

The problem occurs for path components between the first and the last component. I'm trying to use an <a href="{$parentPath}">...</a> to create a link, and it works for the first path element, but not for any of the rest—it only prints the label that goes between the opening and closing tags. I've included commented-out code which demonstrate that it's processing as expected with the exception of this one glitch. (I'm a CS grad student, so recursion has become second nature to me and I'm quite certain the error isn't there. I've debugged this is oXygen, and all the variables had the expected values.)

I also tried the following alternative, which behaves the same:

        <xsl:element name="a">
                <xsl:attribute name="href">
                        <xsl:value-of select="$parentPath"/>
                </xsl:attribute>
                <xsl:text>[root]</xsl:text>
        </xsl:element>

I've been testing my XSL in both Safari 3.1.2 in OS X Leopard and TextXSLT (http://www.entropy.ch/software/macosx/#testxslt) using both Sablotron and libxslt (can't find documentation of which versions it uses, but the latest release is from 2005). This is just the XSL file; since I'm calling the template from <xsl:template match="*"> it will ignore the contents of XML fed to it.

There may be a better way to do what I'm doing, and I'm open to suggestions, although my primary concern is being able to reliably create a link tag. However, I do wonder about what symbol I should use to designate where the parent path begins—right now I'm using $, but this would break if any of the path components contain that symbol. Any thoughts are welcome.

Thanks in advance,
- Quinn Taylor




<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
        <xsl:output method="html"/>
        
        <xsl:template match="*">
                <xsl:call-template name="printRecursivePath">
                        <xsl:with-param 
name="text">/path/to/resource</xsl:with-param>
                </xsl:call-template>
        </xsl:template>
        
        <!-- Split path components at '/', add parent directory links -->
        <xsl:template name="printRecursivePath">
                <xsl:param name="text"/>
                <xsl:variable name="head" select="substring-before($text,'/')"/>
                <xsl:variable name="tail" select="substring-after($text,'/')"/>
                <xsl:if test="$tail">
<!-- Make a tail-recursive call and store the text result in a variable -->
                        <xsl:variable name="recursiveResult">
                                <xsl:call-template name="printRecursivePath">
                                        <xsl:with-param name="text" 
select="$tail"/>
                                </xsl:call-template>
                        </xsl:variable>
                        <!-- Split the parent path from the text generated so far 
-->
<xsl:variable name="generatedText" select="substring- before($recursiveResult,'$')"/> <xsl:variable name="parentPath" select="substring- after($recursiveResult,'$')"/>

                        <xsl:if test="$head">
                                <xsl:text> / </xsl:text>
                                <a href="{$parentPath}"><xsl:value-of 
select="$head"/></a>
<!--
                                <xsl:text>&lt;</xsl:text>
                                <xsl:value-of select="$parentPath"/>
                                <xsl:value-of select="$head"/>
                                <xsl:text>&gt;</xsl:text>
-->                          
                                <!-- Include the processed tail of the path 
components -->
                                <xsl:value-of select="$generatedText"/>
                                <!-- Include the recursively-returned parent path 
at the end -->
                                <xsl:text>$../</xsl:text>
                                <xsl:value-of select="$parentPath"/>
                        </xsl:if>
                        <!-- Prepend a link for the implicit path root -->
                        <xsl:if test="not($head)">
                                <a href="{$parentPath}">[root]</a>
                                <!-- Include the processed text of all path 
components -->
                                <xsl:value-of select="$generatedText"/>
                        </xsl:if>
                </xsl:if>
                <!-- Recursive base case: end of the path -->
                <xsl:if test="not($tail)">
                        <xsl:text> / </xsl:text>
                        <xsl:value-of select="$text"/>
                        <!-- Include the first value for $parentPath -->
                        <xsl:text>$../</xsl:text>
                </xsl:if>
        </xsl:template>
        
</xsl:stylesheet>


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--