RE: [xsl] last index of...

Subject: RE: [xsl] last index of...
From: "McNally, David" <David.McNally@xxxxxxxxxx>
Date: Mon, 12 Nov 2001 15:01:47 -0500
> > Is there a function in XSLT which obtains the position of the last
> > occurrence of a string within another string?
> Getting the last index would be slightly more complicated, and it
> looks like you want to use it to get hold of the string after the last
> occurrence of something, so hopefully this is sufficient.

Here's my attempt at getting the index of the last occurrence - basically
defining a reverse template that just reverses strings, then using
string-length and substring-before on the reversed strings in a template
called rindex.

Using this input file, searching for "nme" in each case:

<test>aaa bbb nme ccc ddd nme aaa 21</test>
<test>aaa bbb nme ccc nme aaa 17</test>
<test>aaa ccc ddd nme aaa 13</test>
<test>aaanmenmenme bbb nme ccc ddd nmenmenme aaa 36</test>
<test>;l sdkjsdf lsdfkj 0</test>

This stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:html="";  >

<xsl:output method="text"/>

<xsl:template name="reverse">
	<xsl:param name="string"/>
	<xsl:value-of select="substring($string, string-length($string))"/>
	<xsl:if test="string-length($string) > 1">
		<xsl:call-template name="reverse">
			<xsl:with-param name="string"
select="substring($string, 1, (string-length($string)-1))"/>

<xsl:template name="rindex">
	<xsl:param name="string"/>
	<xsl:param name="substring"/>
		<xsl:when test="contains($string,$substring)">
			<xsl:variable name="rstring">
				<xsl:call-template name="reverse">
					<xsl:with-param name="string"
			<xsl:variable name="rsubstring">
				<xsl:call-template name="reverse">
					<xsl:with-param name="string"
			<xsl:value-of select="string-length($string) -
(string-length(substring-before($rstring,$rsubstring)) +
string-length($rsubstring)) + 1"/>
			<xsl:value-of select="0"/>

<xsl:template match="test">
Position: </xsl:text>
	<xsl:call-template name="rindex">
		<xsl:with-param name="string" select="."/>
		<xsl:with-param name="substring" select="'nme'"/>


gives output:

Position: 21
Position: 17
Position: 13
Position: 36
Position: 0

which seems right.

I just checked the archives to see if reverse templates had been discussed
before, and indeed they have:

I guess the reverse template I wrote is tail-recursive, and so slow?

David McNally            Moody's Investors Service
Software Engineer        99 Church St, NY NY 10007 
David.McNally@xxxxxxxxxx            (212) 553-7475 

 XSL-List info and archive:

Current Thread