Re: Passing element nodes through string functions (WAS RE: [xsl] Preserving inline elements when using string functions)

Subject: Re: Passing element nodes through string functions (WAS RE: [xsl] Preserving inline elements when using string functions)
From: Brook Ellingwood <brook@xxxxxxxxxxx>
Date: Wed, 10 Sep 2003 11:35:38 -0700
First off, apologies to anyone who was recently spammed by my out of office
reply. I recently changed hosts, and didn't get the filtering preferences
set right. I should have been more careful.

Secondly, I'm revisiting this problem that David provided a solution for,
and I've found case where it breaks down. If the last line (set off by
&#10;) contains a <link> followed by unlinked text, the string after the
</link> is dropped. Basically, the recursive loop is stopping one recursion
too soon. I've tried a few ways of including the substring in the
<xsl:otherwise> escape from the loop, but haven't gotten it right, and I'm
not sure that I'm on the right track. I'd appreciate any insight.

TIA,

-- Brook


XML:

    <body>
        <text>This is the <link url="">link</link>
        This is another line
        This is the third line with another <link url="">link</link>
        This is the fourth line with a <link url="">link</link> embedded in
it</text>
    </body>


XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="html" encoding="UTF-8" indent="yes"/>

<xsl:key name="x" match="text/node()"
use="generate-id((..|preceding-sibling::text()[contains(.,'&#10;')][1])[last
()])"/>

<xsl:template match="page">
    <xsl:apply-templates>
           <xsl:with-param name="textNode"
select="key('x',generate-id(.))[position()&lt;last()]"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="link">
    <a href="{@url}">
        <xsl:apply-templates/>
    </a>
</xsl:template>


<xsl:template match="text">
    <xsl:for-each select=".|text()[contains(.,'&#10;')]">
        <xsl:call-template name="d1">
            <xsl:with-param name="s"
select="substring-after(self::text(),'&#10;')"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>

<xsl:template name="d1">
    <xsl:param name="s"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:choose>
        <xsl:when test="contains($s,'&#10;')">
            <div><xsl:value-of select="substring-before($s,'&#10;')"/></div>
            <xsl:call-template name="d1">
                <xsl:with-param name="s"
select="substring-after($s,'&#10;')"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <div><xsl:value-of select="$s"/>
                <xsl:apply-templates
select="key('x',generate-id(.))[position()&lt;last()]"/>
<xsl:value-of
select="substring-before(key('x',generate-id(.))[last()],'&#10;')"/>
            </div>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

HTML OUTPUT:

<div>This is the <a href="">link</a></div>
<div>    This is another line</div>
<div>    This is the third line with another <a href="">link</a></div>
<div>    This is the fourth line with a <a href="">link</a></div>




 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread