Subject: [xsl] Reverse (Was: RE: last index of...) From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Tue, 13 Nov 2001 04:23:02 -0800 (PST) |
> 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. Two implementations of the reverse function (one of them DVC) can be found at: http://sources.redhat.com/ml/xsl-list/2001-08/msg00243.html Here's a functional implementation: reverse = foldl (flip (:)) [] where (flip (:)) xs x = x:xs ((:) adds an element in front of a list, flip just reverses the order of the arguments), and [] is the empty list. This can be immediately translated to an XSLT implementation using the XSLT implementation of foldl provided at: http://sources.redhat.com/ml/xsl-list/2001-11/msg00214.html However, for this foldl implementation, an XSLT synonym for "list" is a node-set. In this concrete case we want to reverse a string, not a node-set. While in Haskell a string is just a list of characters, in XSLT a string is not a node-set of anything. Therefore, a separate XSLT implementation is needed of a foldl function operating on strings. It can be mechanuically obtained from the foldl we have, by substituting $nodeSet[1] with substring($someString, 1, 1) and $nodeSet[position() > 1] with substring($someString, 2) Here it is: <xsl:template name="str-foldl"> <xsl:param name="pFunc" select="/.."/> <xsl:param name="pA0"/> <xsl:param name="pStr"/> <xsl:choose> <xsl:when test="not($pStr)"> <xsl:copy-of select="$pA0"/> </xsl:when> <xsl:otherwise> <xsl:variable name="vFunResult"> <xsl:apply-templates select="$pFunc[1]"> <xsl:with-param name="arg0" select="$pFunc[position() > 1]"/> <xsl:with-param name="arg1" select="$pA0"/> <xsl:with-param name="arg2" select="substring($pStr,1,1)"/> </xsl:apply-templates> </xsl:variable> <xsl:call-template name="str-foldl"> <xsl:with-param name="pFunc" select="$pFunc"/> <xsl:with-param name="pStr" select="substring($pStr,2)"/> <xsl:with-param name="pA0" select="$vFunResult"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> Now, it is easy to write the strReverse template: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str-reverse-func="f:str-reverse-func" exclude-result-prefixes="xsl str-reverse-func" > <xsl:import href="str-foldl.xsl"/> <str-reverse-func:str-reverse-func/> <xsl:template name="strReverse"> <xsl:param name="pStr"/> <xsl:variable name="vReverseFoldlFun" select="document('')/*/str-reverse-func:*[1]"/> <xsl:call-template name="str-foldl"> <xsl:with-param name="pFunc" select="$vReverseFoldlFun"/> <xsl:with-param name="pStr" select="$pStr"/> <xsl:with-param name="pA0" select="/.."/> </xsl:call-template> </xsl:template> <xsl:template match="str-reverse-func:*"> <xsl:param name="arg1" select="0"/> <xsl:param name="arg2" select="0"/> <xsl:value-of select="concat($arg2,$arg1)"/> </xsl:template> </xsl:stylesheet> Do you notice how easy it is to produce a multitude of important functions using a small number of very general list-processing functions like foldl/foldr, map,... etc.? Just pass some specific functions as parameters to these generic list-processing functions. Cheers, Dimitre Novatchev. __________________________________________________ Do You Yahoo!? Find the one for you at Yahoo! Personals http://personals.yahoo.com XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] forming a link w/ argumen, Jarno . Elovirta | Thread | [xsl] xsl reference in xsl, Eric Chappuis |
Re: [xsl] forming a link w/ argumen, cutlass | Date | RE: [xsl] forming a link w/ argumen, Jarno . Elovirta |
Month |