RE: [xsl] Tracking position in recursive functions?

Subject: RE: [xsl] Tracking position in recursive functions?
From: Emmanuel Bégué <eb@xxxxxxxxxx>
Date: Thu, 2 Apr 2009 09:37:32 +0200
Hello,

You need to recursively send a "position" parameter to increment the
position.

If you simplify your template thusly:

<xsl:template name="str:_tokenize-delimiters">
	<xsl:param name="args"/>
	<xsl:param name="delimiters"/>
	<xsl:param name="pos" select="1"/>

	<xsl:variable name="delimiter" select="substring($delimiters, 1, 1)"/>
	<xsl:variable name="left">
		<xsl:choose>
			<xsl:when test="not(contains($args,$delimiter))">
				<xsl:value-of select="$args"/>
				</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="substring-before($args,$delimiter)"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
	<xsl:variable name="right" select="substring-after($args,$delimiter)"/>
	<xsl:if test="$left != ''">
		<option pos="{$pos}"><xsl:value-of select="$left"/></option>
		</xsl:if>
	<xsl:if test="$right != ''">
		<xsl:call-template name="str:_tokenize-delimiters">
			<xsl:with-param name="args" select="$right"/>
			<xsl:with-param name="delimiters" select="$delimiters"/>
			<xsl:with-param name="pos" select="$pos + 1"/>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>

(with just one recursive call instead of three, and just one writing
of the <option> element)

you get:
for the source string ('args'): one two three four
and the space delimiter
the following result:

	<option pos="1">one</option>
	<option pos="2">two</option>
	<option pos="3">three</option>
	<option pos="4">four</option>

Regards,
EB

> -----Original Message-----
> From: himanshu padmanabhi [mailto:himanshu.padmanabhi@xxxxxxxxx]
> Sent: Thursday, April 02, 2009 8:56 AM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Tracking position in recursive functions?
>
>
> Hi,
>
> These is just the part of str::tokenize.
>
> I just want to ask how to track "position" in recursive functions like
> "str:_tokenize-delimiters"?
>
> "position()" isn't solving the purpose.
>
> "$args" value is "-p 10 -t 20 abcd.domain.com" which I want to
> tokenize by space.
>
> What my final goal is,
> If called with position()=1 then print 2nd pos = 10
> If called with position()=2 then print 4nd pos = 20
> If called with position()=3 then print 5nd pos = abcd.domain.com
> (There are 3 xml elements so str:tokenize can be called 3 times or I
> call it 1 time and save 2,4,5 values in variables and can print it in
> calling template.)
>
> Currently it is printing all the tokens each time.
> Tracking 'position' in recursive function also can give me answer like
> 2nd,4th,5th position token.
>
> <xsl:stylesheet version="1.0"
>                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>                 xmlns:str="http://exslt.org/strings";
>                 extension-element-prefixes="str">
>
> <xsl:template name="str:_tokenize-delimiters">
>   <xsl:param name="args" />
>   <xsl:param name="delimiters" />
>
>   <xsl:variable name="delimiter" select="substring($delimiters, 1, 1)" />
>
>   <xsl:choose>
>         <xsl:when test="not($delimiter)" >
>             <option><xsl:value-of select="$args" /></option>
>         </xsl:when>
>
>     <xsl:when test="contains($args, $delimiter)">
>         <option><xsl:value-of select="substring-after($args,
> $delimiter)" /></option>
>         <xsl:if test="not(starts-with($args, $delimiter))">
>             <xsl:call-template name="str:_tokenize-delimiters">
>                 <xsl:with-param name="args"
> select="substring-before($args, $delimiter)" />
>                 <xsl:with-param name="delimiters"
> select="substring($delimiters, 2)" />
>             </xsl:call-template>
>         </xsl:if>
>
>         <xsl:call-template name="str:_tokenize-delimiters">
>             <xsl:with-param name="args" select="substring-after($args,
> $delimiter)" />
>             <xsl:with-param name="delimiters" select="$delimiters" />
>         </xsl:call-template>
>     </xsl:when>
>
>     <xsl:otherwise>
>         <xsl:call-template name="str:_tokenize-delimiters">
>             <xsl:with-param name="args" select="$args" />
>             <xsl:with-param name="delimiters"
> select="substring($delimiters, 2)" />
>         </xsl:call-template>
>     </xsl:otherwise>
>   </xsl:choose>
> </xsl:template>
>
> </xsl:stylesheet>
> ---------------------------------
> Thanks and Regards,
> Himanshu Padmanabhi

Current Thread