Subject: Re: [xsl] Need assistance with conditional logic and counter in XSLT 2.0 From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> Date: Tue, 20 Mar 2012 15:42:00 -0400 |
<xsl:template match="Order"> <div class="order"> <xsl:apply-templates/> </div> </xsl:template>
<xsl:template name="entry"> <xsl:param name="label"/> <xsl:if test="normalize-space()"> <!-- don't generate output for elements that have no contents or only whitespace contents --> <p> <xsl:call-template name="number"/> <xsl:value-of select="$label"/> <xsl:text>: </xsl:text> <xsl:apply-templates/> </p> </xsl:if> </xsl:template>
<xsl:template name="number"> <xsl:number level="multiple" format="1.1. " count="OrderNumber[normalize-space()] | CustomerID[normalize-space()] | Return[normalize-space()] | ReturnReason[normalize-space()] | Total[normalize-space()]"/> </xsl:template>
<xsl:template match="OrderNumber"> <xsl:call-template name="entry"> <xsl:with-param name="label">Order number</xsl:with-param> </xsl:call-template> </xsl:template>
<xsl:template match="CustomerID"> <xsl:call-template name="entry"> <xsl:with-param name="label">Customer ID</xsl:with-param> </xsl:call-template> </xsl:template>
<xsl:template match="Return"> <xsl:if test="normalize-space()"> <p> <xsl:call-template name="number"/> <xsl:text>Return Date: </xsl:text> <xsl:apply-templates select="ReturnDate"/> </p> <xsl:apply-templates select="ReturnReason"/> </xsl:if> </xsl:template>
<xsl:template match="ReturnReason"> <xsl:call-template name="entry"> <xsl:with-param name="label">Reason</xsl:with-param> </xsl:call-template> </xsl:template>
<xsl:template match="Total"> <xsl:call-template name="entry"> <xsl:with-param name="label">Total</xsl:with-param> </xsl:call-template> </xsl:template>
Cheers, Wendell
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<= 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>
-- ====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Need assistance with cond, Terry Badger | Thread | [xsl] XPath to Find All Siblings Ex, Rick Quatro |
RE: [xsl] RE: String conversion pro, Bulgrien, Kevin | Date | RE: [xsl] String conversion problem, Bulgrien, Kevin |
Month |