This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Is recursion in XSL really this difficult?


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]