[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Overflow on building relative paths for one case only


Subject: RE: [xsl] Overflow on building relative paths for one case only
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sat, 12 Jan 2008 18:18:18 -0000

> It looks like your problem is associated with setting your 
> variable $samePath to the boolean true() or false(), and then 
> later on checking if $samePath equals the string 'false':

That doesn't look wrong to me. <xsl:value-of select="false()"/> will create
a text node whose string value is "false", just as if you wrote
<xsl:text>false</xsl:text>. 

Moreover, <xsl:when test="not($samePath)"> is definitely wrong. $samePath is
a result tree fragment, and converting a result tree fragment to a boolean
should always give true.

Looking at the logic, why not make $samePath a boolean variable? This is
possible even in XSLT 1.0:

<xsl:variable name="samePath" select="$to=$from and
not(contains(substring-after(substring-after($to,$from),'/'),'/'))"/>.
Replaces 20 lines of code by one, and if you can do that a few times then
more of us might be inclined to look at the code and help you with it.

In fact that immediately seems to show a flaw: if $to=$from and both are
strings, then substring-after($to, $from) is "", and substring-after("",
"/") is "", and contains("", "/") is false, so the condition reduces further
to:

<xsl:variable name="samePath" select="$to=$from"/>

Michael Kay
http://www.saxonica.com/

> 
> > <xsl:template name="relativeUrl">
> >  <xsl:param name="from"/>
> >  <xsl:param name="to"/>
> >  <xsl:variable name="samePath">
> >   <xsl:choose>
> >    <!--<xsl:when test="starts-with($to,$from)">-->
> >    <xsl:when test="$to=$from">
> >     <xsl:choose>
> >      <xsl:when
> >      
> test="contains(substring-after(substring-after($to,$from),'/'),'/')">
> >       <xsl:value-of select="false()"/>
>                              ^^^^^^^^^
> >      </xsl:when>
> >      <xsl:otherwise>
> >       <xsl:value-of select="true()"/>
>                              ^^^^^^^^
> >      </xsl:otherwise>
> >     </xsl:choose>
> >    </xsl:when>
> >    <xsl:otherwise>
> >     <xsl:value-of select="false()"/>
>                            ^^^^^^^^^
> >    </xsl:otherwise>
> >   </xsl:choose>
> >  </xsl:variable>
> >  <xsl:choose>
> >   <xsl:when test="$samePath='false'">
>                    ^^^^^^^^^^^^^^^^^^^
> If you change that last xsl:when to:
> 
> >   <xsl:when test="not($samePath)">
> 
> uou should be all set.  For the example you provided, I get:
> 
> <html>
>    <head>
>       <meta http-equiv="Content-Type" content="text/html; 
> charset=utf-8">
> 
>       <title>Getting relative paths</title>
>    </head>
>    
> <body>/web_cabinet/folder1/folder2/folder3<br>/web_cabinet/fol
> der1/folder2/linkingToDocument.doc<br></body>
> </html>
> 
> Cheers,
> 
> ...sam 


Current Thread
Keywords