Subject: Re: [xsl] Total of calculated values from separate templates. From: Neil Williams <linux@xxxxxxxxxxxxxx> Date: Sat, 4 Mar 2006 21:03:55 +0000 |
On Friday 03 March 2006 11:23 am, Neil Williams wrote: Is it possible to calculate values from other calculated values? No matter how I arrange it, I cannot get a simple total! The variables are always out of scope and when I scope them, I can't sum them because one or other gets dumped out as NaN and the whole thing is trashed. > From this XML: > (a snippet of a larger file) > > <?xml version="1.0" encoding="UTF-8"?> > <qof-qsf xmlns="http://qof.sourceforge.net/"> > <book count="1"> > <object type="pilot_datebook" count="1"> > <date type="start_time">2005-11-04T09:00:00Z</date> > <date type="end_time">2005-11-04T17:30:00Z</date> > </object> > <object type="pilot_expenses" count="2"> > <string type="type_of_expense">Parking</string> > <numeric type="expense_amount">160/100</numeric> > <date type="expense_date">2005-11-04T00:00:00Z</date> > </object> > <object type="pilot_expenses" count="3"> > <string type="type_of_expense">Mileage</string> > <numeric type="expense_amount">4000/100</numeric> > <date type="expense_date">2005-11-04T00:00:00Z</date> > </object> > </book> > </qof-qsf> > > I can calculate the duration of the event, multiply that by a default rate > to get an invoice entry and then process the two expenses to create their > own invoice entries: one for parking, one for the mileage, using a default > mileage rate. The numeric string represents amount/denominator. > > I can't see how to: > Generate a total for the entire invoice. I still can't generate the simplest of totals - let alone subtotals for multiple invoices. > basic stylesheet: > <?xml version='1.0'?> > <xsl:stylesheet version="1.1" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:qof-qsf="http://qof.sourceforge.net/" > xmlns:html="http://www.w3.org/1999/xhtml" > xmlns:dt="http://xsltsl.org/date-time" > xmlns:date="http://exslt.org/dates-and-times" > xmlns:str="http://xsltsl.org/string"> > <xsl:import href="date-time.xsl"/> > <xsl:import href="string.xsl"/> > <xsl:import href="./date/functions/difference/date.difference.xsl" /> > <xsl:output method="html"/> > > <!-- user configuration --> > <xsl:param name="mileage-rate">0.3</xsl:param> > <xsl:param name="hourly-rate">20</xsl:param> > <!-- end configuration --> > > <xsl:template match="/"> > <html lang="en"><head></head><body> > <xsl:text> > </xsl:text> > <xsl:apply-templates > select="/*/qof-qsf:book/qof-qsf:object[@type='pilot_datebook']"/> > <xsl:apply-templates > select="/*/qof-qsf:book/qof-qsf:object[@type='pilot_expenses']"/> > <xsl:text> > Total: </xsl:text> > > <xsl:text> > </xsl:text> > </body> > </html> > </xsl:template> > > <xsl:template > match="/*/qof-qsf:book/qof-qsf:object[@type='pilot_datebook']"> > > <xsl:variable name="diff_string"> > <xsl:call-template name="date:difference"> > <xsl:with-param name="start" select="qof-qsf:date[@type='start_time']" > /> <xsl:with-param name="end" select="qof-qsf:date[@type='end_time']" /> > </xsl:call-template> > </xsl:variable> > <xsl:variable name="diff_secs" select="date:seconds($diff_string)"/> > <xsl:value-of select="floor($diff_secs div 3600)"/> > <xsl:text> hours, </xsl:text> > <xsl:value-of select="($diff_secs mod 3600) div 60"/> > <xsl:text> minutes @ </xsl:text> > <xsl:value-of select="format-number($hourly-rate, '######.00')"/> > <xsl:text>/hr = </xsl:text> > <xsl:param name="value"> > <xsl:value-of select="number($diff_secs div 3600 * $hourly-rate)"/> > </xsl:param> > <xsl:value-of select="format-number(($value), '#####.00')"/> > > <xsl:text> > </xsl:text> > </xsl:template> > > <xsl:template > match="/*/qof-qsf:book/qof-qsf:object[@type='pilot_expenses']"> <xsl:param > name="numeric_string" select="qof-qsf:numeric"/> > <xsl:param name="before" select="substring-before($numeric_string, '/')"/> > <xsl:param name="after" select="substring-after($numeric_string, '/')"/> > <xsl:param name="numeric" select="$before div $after"/> > > <xsl:param name="type" select="qof-qsf:string[@type='type_of_expense']"/> > <xsl:choose> > <xsl:when test="$type='Mileage'"> > <xsl:param name="miles" select='number($numeric)'/> > <xsl:param name="value" select="(number($miles * $mileage-rate))"/> > <xsl:value-of select="format-number(($miles), '#####.#')"/> > <xsl:text> miles @ </xsl:text> > <xsl:value-of select="format-number($mileage-rate * 100, '##')"/> > <xsl:text>p/mile = </xsl:text> > <xsl:value-of select="format-number(($value), '#####.00')"/> > <xsl:variable name="subtotal"> > <span><xsl:value-of select="number($value)"/></span> > </xsl:variable> > </xsl:when> > <xsl:otherwise> > <xsl:value-of select="$type"/> > <xsl:text> = </xsl:text> > <xsl:param name="value" select='(number($numeric))'/> > <xsl:value-of select="format-number(($value), '#####.00')"/> > <xsl:variable name="subtotal"> > <span><xsl:value-of select="number($value)"/></span> > </xsl:variable> > <xsl:text> > </xsl:text> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > > </xsl:stylesheet> > > Output from the XML above using xsltproc: > <html lang="en"> > <head><meta http-equiv="Content-Type" content="text/html; > charset=UTF-8"></head> > <body> > 8 hours, 30 minutes @ 20.00/hr = 170.00 > Parking = 1.60 > 40 miles @ 30p/mile = 12.00 > Total: > </body> > </html> > > What I wanted was: > <html lang="en"> > <head><meta http-equiv="Content-Type" content="text/html; > charset=UTF-8"></head> > <body> > 8 hours, 30 minutes @ 20.00/hr = 170.00 > Parking = 1.60 > 40 miles @ 30p/mile = 12.00 > Total: 183.60 > </body> > </html> > > Do I have to create an intermediate nodeset/tree? (how?) > > :-) Help! -- Neil Williams ============= http://www.data-freedom.org/ http://www.nosoftwarepatents.com/ http://www.linux.codehelp.co.uk/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Total of calculated value, Neil Williams | Thread | [xsl] Javascript variable to XSL va, manoj kumar |
[xsl] XSLT as a programming languag, Laurent Lasudry | Date | Re: [xsl] IE's conditional comments, M. David Peterson |
Month |