[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: last index of...

Subject: RE: last index of...
From: "McNally, David" <David.McNally@xxxxxxxxxx>
Date: Mon, 12 Nov 2001 15:01:47 -0500
xsl last index of
> > Is there a function in XSLT which obtains the position of the last
> > occurrence of a string within another string?
> 
[snip]
> 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:

<foo>
<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>
</foo>

This stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:html="http://www.w3.org/1999/xhtml"  >

<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:call-template>
	</xsl:if>
</xsl:template>

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

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

</xsl:stylesheet>

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:
http://www.biglist.com/lists/xsl-list/archives/200108/msg00248.html

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

David.
--
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:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.