Subject: RE: [xsl] Summing a Calculation From: Mark Swardstrom <mark@xxxxxxxxxx> Date: Fri, 22 Jun 2001 10:16:55 -0700 |
Thanks, Jeni. I appreciate your thoughts very much. I see the distinction you make with the two approaches to nesting and agree they're cleaner. Thanks for taking the time to explain. - Mark -----Original Message----- From: Jeni Tennison [mailto:mail@xxxxxxxxxxxxxxxx] Sent: Thursday, June 21, 2001 11:14 PM To: Mark Swardstrom Cc: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Subject: Re: [xsl] Summing a Calculation Hi Mark, > I need to multiply each line by the quantity to get the amount per item. [snip] > Here's my current solution, but would like to reduce: Your current solution looks pretty good. Personally, I'd *either* use a matching template that traversed the item elements using the following-sibling:: axis *or* use a named template that took a node set as a parameter and walked over that by splitting it into the 'first' and 'rest'. Your solution mixes the two approaches. Just to show you what I mean, here's a matching template approach: <xsl:template match="item" mode="calcTotal"> <xsl:param name="subtotal" select="0" /> <xsl:variable name="total" select="$subtotal + (price * quantity)" /> <xsl:choose> <xsl:when test="not(following-sibling::item)"> <xsl:value-of select="$total" /> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="following-sibling::item[1]" mode="calcTotal"> <xsl:with-param name="subtotal" select="$total" /> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:template> And you'd use it like: <xsl:variable name="total"> <xsl:apply-templates select="item[1]" /> </xsl:variable> <xsl:value-of select="format-number($total, '$#,##0.00')"/> And here's the named template approach: <xsl:template name="calcTotal"> <xsl:param name="nodes" select="/.." /> <xsl:param name="subtotal" select="0" /> <xsl:variable name="total" select="$subtotal + ($nodes[1]/price * $nodes[1]/quantity)" /> <xsl:choose> <xsl:when test="not($nodes[2])"> <xsl:value-of select="$total" /> </xsl:when> <xsl:otherwise> <xsl:call-template name="calcTotal"> <xsl:with-param name="nodes" select="$nodes[position() > 1]" /> <xsl:with-param name="subtotal" select="$total" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> And you'd use it like: <xsl:variable name="total"> <xsl:call-template name="calcTotal"> <xsl:with-param name="nodes" select="item" /> </xsl:call-template> </xsl:variable> <xsl:value-of select="format-number($total, '$#,##0.00')"/> Personally, I prefer the matching template approach because it's shorter and easier to call. However, it has the disadvantage of being very closely tied to the source XML - it uses the fact that the nodes you're summing are sibling item elements. The named template is more generic because it can use any node set, and you could make it even more so by having the calculated value (i.e. price * quantity in this case) for a node be calculated in a separate template (or even in a user-defined function if you like that kind of thing). How specific or generic you want to make it obviously depends on your goals for the stylesheet. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Summing a Calculation, Jeni Tennison | Thread | [xsl] multiple test?, Dennis Luemkemann |
[xsl] Installing MSXML3 in replace , Elina Bidner | Date | Re: [xsl] Executing variable XPath , Jeni Tennison |
Month |