[xsl] reverse() template (Was: RE: XSL output method="text" and indent preservation)

Subject: [xsl] reverse() template (Was: RE: XSL output method="text" and indent preservation)
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 3 Aug 2001 21:52:39 -0700 (PDT)
Jarno Elovirta wrote:

> > have one issue. In
> > your suggestion you had given it to get the substring after 
> > the FIRST occurrence
> > of the new line character, of preceding element. I would like 
> > to get the
> > substring after the LAST occurrence of the new line 
> > character.  It would give me
> > the white spaces only, in my case. It would be a great help, 

[snip]

> Or write an extension function for
> 
> substring-after(exf:reverse(preceding::text()[1]), '&#xA;')


Here are two templates for reversing a string. The first is much faster and more
straightforward, the second will almost never cause an XSLT processor to crash due
to deep recursive processing (it has a maximum recursion depth of only 20 for
reversing a 1MB long string):


<xsl:template name="reverse">
  <xsl:param name="theString"/>
	
  <xsl:variable name="thisLength" select="string-length($theString)"/>
	<xsl:choose>
		<xsl:when test="$thisLength = 1">
			<xsl:value-of select="$theString"/>
		</xsl:when>
		<xsl:otherwise>
			<xsl:variable name="restReverse">
			    <xsl:call-template name="reverse">
			      <xsl:with-param name="theString"
				 select="substring($theString, 1, $thisLength -1)"/>
			    </xsl:call-template>
			</xsl:variable>
			<xsl:value-of 
			  select="concat(substring($theString,
                                                   $thisLength, 
                                                   1
                                                   ) 
                                                    ,$restReverse
                                         )"/>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>


<xsl:template name="reverse2">
  <xsl:param name="theString"/>
  <xsl:variable name="thisLength" select="string-length($theString)"/>
	<xsl:choose>
		<xsl:when test="$thisLength = 1">
		    <xsl:value-of select="$theString"/>
		</xsl:when>
		<xsl:otherwise>
		    <xsl:variable name="length1" select="floor($thisLength div 2)"/>
		    <xsl:variable name="reverse1">
			<xsl:call-template name="reverse2">
			    <xsl:with-param name="theString"
				select="substring($theString, 1, $length1)"/>
			</xsl:call-template>
		    </xsl:variable>
		    <xsl:variable name="reverse2">
			<xsl:call-template name="reverse2">
			    <xsl:with-param name="theString"
				select="substring($theString, 
                                                  $length1+1, 
		                                  $thisLength - $length1
                                                  )"/>
			</xsl:call-template>
		    </xsl:variable>
		    <xsl:value-of select="concat($reverse2, $reverse1)"/>

		</xsl:otherwise>
	</xsl:choose>
</xsl:template>



Cheers,
Dimitre Novatchev.

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail
http://personal.mail.yahoo.com/

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread