[xsl] Is recursion in XSL really this difficult?

Subject: [xsl] Is recursion in XSL really this difficult?
From: "xmlhack ." <xmlhack@xxxxxxxxxxx>
Date: Tue, 17 Jul 2001 19:46:25 -0000
I posted a question about recursion a day or two ago, but all of my efforts since then have been unsuccessful.

What I need to do is search a text node for a string and add bolding around that string when it's found (for HTML output). I CAN do that thanks to Kay's example in the XSLT book. But what I need to do now is recurse over THE ENTIRE string -- not just a piece of it -- a second and third time to find matches for a second and third string.

Based on what I've seen in my failed attempts, I think what I need to do is store the entire text node in a string (or node set...no more temp trees, right?), process it the first time, process it a second time, and process it a third time. But, all my attempts to do this have resulted in the text node being output 3 times.

If you can help, please let me know!

The below is my original coding that works in a limited fashion:

<xsl:param name="id" />
<xsl:param name="p1" />
<xsl:param name="p2" />
<xsl:param name="p3" />
<xsl:param name="p4" />
<xsl:param name="p5" />
<xsl:param name="upper">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:param>
<xsl:param name="lower">abcdefghijklmnopqrstuvwxyz</xsl:param>
<xsl:param name="left">&#62;&#62;</xsl:param>
<xsl:param name="right">&#60;&#60;</xsl:param>

<xsl:template name="do-replace">
	<xsl:param name="text" />

<xsl:choose>
<xsl:when test="contains(translate($text,$upper,$lower), translate($p1,$upper,$lower))">
<xsl:choose>
<xsl:when test="$p1!=''">
<!--length of the text string to be analyzed-->
<xsl:param name="length">
<xsl:value-of select="string-length(substring-before(translate($text,$upper,$lower), translate($p1,$upper,$lower)))" />
</xsl:param>


			<!--length of the search parameter-->
			<xsl:param name="lengthandstring">
			<xsl:value-of select="string-length($p1)" />
			</xsl:param>

			<xsl:param name="lengthplusone">
			<xsl:value-of select="$length + 1" />
			</xsl:param>

<!--first portion of text string-->
<xsl:value-of select="substring($text,1,$length)" />
<span class="searchresult">
<xsl:value-of select="$left" />
<!--the matched text-->
<xsl:value-of select="normalize-space(substring($text,$lengthplusone,$lengthandstring))" />
<xsl:value-of select="$right" />
</span>


<!--where the next text string should start, as a piece of the current string-->
<xsl:param name="start">
<xsl:value-of select="$length + string-length($p1) + 1" />
</xsl:param>


<xsl:call-template name="do-replace">
<xsl:with-param name="text" select="substring($text,$start)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="contains(translate($text,$upper,$lower), translate($p2,$upper,$lower))">
<xsl:choose>
<xsl:when test="$p2!=''">
<xsl:param name="length">
<xsl:value-of select="string-length(substring-before(translate($text,$upper,$lower), translate($p2,$upper,$lower)))" />
</xsl:param>


			<xsl:param name="lengthandstring">
			<xsl:value-of select="string-length($p2)" />
			</xsl:param>

			<xsl:param name="lengthplusone">
			<xsl:value-of select="$length + 1" />
			</xsl:param>

<xsl:value-of select="substring($text,1,$length)" />
<span class="searchresult">
<xsl:value-of select="$left" />
<xsl:value-of select="normalize-space(substring($text,$lengthplusone,$lengthandstring))" />
<xsl:value-of select="$right" />
</span>


			<xsl:param name="start">
			<xsl:value-of select="$length + string-length($p2) +1" />
			</xsl:param>

			<xsl:call-template name="do-replace">
				<xsl:with-param name="text" select="substring($text,$start)" />
			</xsl:call-template>
		</xsl:when>
		<xsl:otherwise>
			<xsl:value-of select="$text" />
		</xsl:otherwise>
		</xsl:choose>
	</xsl:when>
	<xsl:otherwise>
		<xsl:value-of select="$text" />
	</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<xsl:template match="*">
	<xsl:copy>
	<xsl:copy-of select="@*" />
	<xsl:apply-templates />
	</xsl:copy>
</xsl:template>

<xsl:template match="text()">
	<xsl:call-template name="do-replace">
		<xsl:with-param name="text" select="." />
	</xsl:call-template>
</xsl:template>



_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com


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



Current Thread