[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Need assistance with conditional logic and counter in XSLT 2.0


Subject: Re: [xsl] Need assistance with conditional logic and counter in XSLT 2.0
From: Emmanuel Bégué <medusis@xxxxxxxxx>
Date: Wed, 14 Mar 2012 16:02:50 +0100

A recursive template is not needed if the number you want to display
is equal to the position of the node being evaluated. This result (a
little different from what you want):

1. OrderNumber: 1235
2. CustomerID: 233
3.1. ReturnDate: 3/15/2011
3.2. ReturnReason: Too small
4. Total: $455

can be obtained with these templates:

<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="Order">
	<xsl:apply-templates/>
	</xsl:template>
<xsl:template match="Return">
	<xsl:variable name="parent-pos" select="concat(position(), '.')"/>
	<xsl:apply-templates>
		<xsl:with-param name="parent-pos" select="$parent-pos"/>
		</xsl:apply-templates>
	</xsl:template>
<xsl:template match="*">
	<xsl:param name="parent-pos"/>
	<xsl:value-of select="$parent-pos"/>
	<xsl:value-of select="concat(position(), '.')"/>
	<xsl:value-of select="concat(' ', name(), ': ', ., '&#x000D;&#x000A;')"/>
	</xsl:template>

Hope this helps.

Regards,
EB



2012/3/14 Jennifer Elkhouri <jwelkhouri@xxxxxxxxx>:
> I am very new to XSLT, so thank you in advance for helping me out. My
> issue is related to wanting to print output conditionally using
> counters. If an element returns no data, I do not want to print the
> header for that section (easy enough). However, these headers need to
> be numbered ... which is where I am having a problem.
>
> For example, given:
>
>  (XML for record 1234):
>  <Order>
>   <OrderNumber>1234</OrderNumber>
>   <CustomerID>111</CustomerID>
>   <Return/>
>   <Total>$344</Total>
>  </Order>
>
>  (XML for record 1235):
>  <Order>
>    <OrderNumber>1235</OrderNumber>
>    <CustomerID>233</CustomerID>
>    <Return>
>       <ReturnDate>3/15/2011</ReturnDate>
>       <ReturnReason>Too small</ReturnDate>
>    </Return>
>    <Total>$455</Total>
>  </Order>
>
>  If someone selected record 1, they expect the transformed html output to
be:
>
>  1. Order Number: 1234
>  2. Customer ID: 111
>  3. Total: $344
>
>  If someone selected record 2, they expect the transformed html output to
be:
>  1. Order Number: 1235
>  2. Customer ID: 233
>  3. Return Date: 3/15/2011
>  3.1. Return Reason: Too small
>  4. Total: $455
>
> I learned quite quickly that I can't do a simple counter. From what
> I've read, it is suggested that I use a recursive template. Can you
> please help me?
>
> Below is my sample code ... (only showing a snippet for brevity. I am
> using XSLT 2.0 and have set a global variable of newLine for a
> carriage return.)
>
> <xsl:value-of select="/Order/OrderNumber" /><xsl:text>Order Number:
</xsl:text>
> <xsl:call-template name="counter">
>    <xsl:with-param name="index" select="position()"/>
> </xsl:call-template> <xsl:value-of select="$newLine" />
>
> <xsl:value-of select="/Order/CustomerID" /><xsl:text>Customer ID:
</xsl:text>
> <xsl:call-template name="counter">
> <xsl:with-param name="index" select="position()"/>
> </xsl:call-template> <xsl:value-of select="$newLine" />
>
> <xsl:if test="/Order/Return/ReturnDate">
>    <xsl:value-of select="/Order/Return/ReturnDate" /><xsl:text>Return
> Date: </xsl:text>
>    <xsl:call-template name="counter">
>     <xsl:with-param name="index" select="position()"/>
>    </xsl:call-template> <xsl:value-of select="$newLine" />
>
>    <xsl:value-of select="/Order/Return/ReturnReason"
> /><xsl:text>Return Reason: </xsl:text>
>    <xsl:call-template name="counter">
>    <xsl:with-param name="index" select="position()"/>
>    </xsl:call-template> <xsl:value-of select="$newLine" />
>
> </xsl:if>
>
> <xsl:value-of select="/Order/Total" /><xsl:text>Total: </xsl:text>
> <xsl:call-template name="counter">
> <xsl:with-param name="index" select="position()"/>
> </xsl:call-template> <xsl:value-of select="$newLine" />
>
> <xsl:template name="counter">
>   <xsl:param name="index" select="1"/>
>   <xsl:if test="$index &lt;= 10">            <!-- I put this in here
> so it doesn't fall into an infinite loop. There's got to be a better
> way? -->
>     <xsl:value-of select="$index"/>
>     <xsl:call-template name="counter">
>       <xsl:with-param name="index" select="$index + 1"/>
>     </xsl:call-template>
>   </xsl:if>
> </xsl:template>


Current Thread
Keywords