[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] RE: 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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|