cmain
asked on
xslt + NaN
Hi,
I am trying to sum up a value using a published algorithm. The algoritm seems to get the correct value, but I cannot seem to format the value without getting NaN. Could anyone help.
Here is the XML.
<client name='Joe Bloggs'>
<supplier name='A'>
<product name='C'>
<investment name='D='1200' price='5.50'/>
<investment name='E' units='1200' price='3.50'/>
<investment name='F' units='1345' price='6.55'/>
</product>
</supplier>
<supplier name='B'>
<product name='E'>
<investment name='T' units='1200' price='5.50'/>
<investment name='W' units='1200' price='3.50'/>
<investment name='S' units='1345' price='6.55'/>
</product>
</supplier>
</client>
And here is the xslt.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-m icrosoft-c om:xslt"
xmlns:palantir="http://www.palantir.co.za"
version="1.0">
<xsl:output
method = "xml"
version = "1.0"
encoding = "UTF-8"
indent = "yes"/>
<msxsl:script language="VBScript" implements-prefix="palanti r">
<![CDATA[
Function Format(value)
Format = value
'Format = FormatCurrency(value)
End Function
]]>
</msxsl:script>
<xsl:template match="/">
<table>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match='client'>
<tr>
<td><xsl:value-of select='@name'/></td>
<td>
<xsl:call-template name='total-investment'>
<xsl:with-param name='investment-set' select='//investment'/>
</xsl:call-template>
</td>
</tr>
</xsl:template>
<xsl:template name='total-investment'>
<xsl:param name='investment-set'/>
<xsl:choose>
<xsl:when test='$investment-set'>
<xsl:variable name='first-node'>
<xsl:apply-templates select='$investment-set[1] ' mode='investment-price'/>
</xsl:variable>
<xsl:variable name='other-nodes'>
<xsl:call-template name='total-investment'>
<xsl:with-param name='investment-set' select='$investment-set[po sition()!= 1]'/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select='palantir:Format(nu mber(numbe r($first-n ode) + number($other-nodes)))'/>
</xsl:when>
<xsl:otherwise>0</xsl:othe rwise>
</xsl:choose>
</xsl:template>
<xsl:template match='investment' mode='investment-price'>
<xsl:value-of select='@units * @price'/>
</xsl:template>
</xsl:stylesheet>
The above xslt works, except when I comment back in the format code it doesn't work.
I have tried the xslt built in functions, and I am getting the same result.
Please help.
Regards
-craig.
I am trying to sum up a value using a published algorithm. The algoritm seems to get the correct value, but I cannot seem to format the value without getting NaN. Could anyone help.
Here is the XML.
<client name='Joe Bloggs'>
<supplier name='A'>
<product name='C'>
<investment name='D='1200' price='5.50'/>
<investment name='E' units='1200' price='3.50'/>
<investment name='F' units='1345' price='6.55'/>
</product>
</supplier>
<supplier name='B'>
<product name='E'>
<investment name='T' units='1200' price='5.50'/>
<investment name='W' units='1200' price='3.50'/>
<investment name='S' units='1345' price='6.55'/>
</product>
</supplier>
</client>
And here is the xslt.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-m
xmlns:palantir="http://www.palantir.co.za"
version="1.0">
<xsl:output
method = "xml"
version = "1.0"
encoding = "UTF-8"
indent = "yes"/>
<msxsl:script language="VBScript" implements-prefix="palanti
<![CDATA[
Function Format(value)
Format = value
'Format = FormatCurrency(value)
End Function
]]>
</msxsl:script>
<xsl:template match="/">
<table>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match='client'>
<tr>
<td><xsl:value-of select='@name'/></td>
<td>
<xsl:call-template name='total-investment'>
<xsl:with-param name='investment-set' select='//investment'/>
</xsl:call-template>
</td>
</tr>
</xsl:template>
<xsl:template name='total-investment'>
<xsl:param name='investment-set'/>
<xsl:choose>
<xsl:when test='$investment-set'>
<xsl:variable name='first-node'>
<xsl:apply-templates select='$investment-set[1]
</xsl:variable>
<xsl:variable name='other-nodes'>
<xsl:call-template name='total-investment'>
<xsl:with-param name='investment-set' select='$investment-set[po
</xsl:call-template>
</xsl:variable>
<xsl:value-of select='palantir:Format(nu
</xsl:when>
<xsl:otherwise>0</xsl:othe
</xsl:choose>
</xsl:template>
<xsl:template match='investment' mode='investment-price'>
<xsl:value-of select='@units * @price'/>
</xsl:template>
</xsl:stylesheet>
The above xslt works, except when I comment back in the format code it doesn't work.
I have tried the xslt built in functions, and I am getting the same result.
Please help.
Regards
-craig.
The following is a more succinct and better performing stylesheet
Recommended XSLT Document
========================== =
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:msxsl="urn:schemas-m icrosoft-c om:xslt" exclude-result-prefixes="m sxsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<table><xsl:apply-template s/></table >
</xsl:template>
<xsl:template match="client">
<xsl:variable name="total-list">
<xsl:for-each select="descendant::invest ment">
<sum><xsl:value-of select="@units * @price" /></sum>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="sum" select="sum(msxsl:node-set ($total-li st)/node() )" />
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="format-number($sum ,'#,###,## 0.00')" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Recommended XSLT Document
==========================
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:msxsl="urn:schemas-m
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<table><xsl:apply-template
</xsl:template>
<xsl:template match="client">
<xsl:variable name="total-list">
<xsl:for-each select="descendant::invest
<sum><xsl:value-of select="@units * @price" /></sum>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="sum" select="sum(msxsl:node-set
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="format-number($sum
</tr>
</xsl:template>
</xsl:stylesheet>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks very much.
I have used a hybrid of your last suggestion as I wish to use parameters and sum at several different levels.
I am still a tad unsure of why I was getting the NaN value, although I will look at it in more detail. Your solution works perfectly, thanks.
Regards
-craig.
I have used a hybrid of your last suggestion as I wish to use parameters and sum at several different levels.
I am still a tad unsure of why I was getting the NaN value, although I will look at it in more detail. Your solution works perfectly, thanks.
Regards
-craig.
MODIFIED XSLT DOCUMENT
======================
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method = "xml" version = "1.0" encoding = "UTF-8" indent = "yes"/>
<xsl:template match="/">
<table>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match='client'>
<xsl:variable name="sum">
<xsl:call-template name='total-investment'>
<xsl:with-param name='investment-set' select='//investment'/>
</xsl:call-template>
</xsl:variable>
<tr>
<td><xsl:value-of select='@name'/></td>
<td><xsl:value-of select="format-number($sum
</tr>
</xsl:template>
<xsl:template name='total-investment'>
<xsl:param name='investment-set'/>
<xsl:choose>
<xsl:when test='$investment-set'>
<xsl:variable name='first-node'>
<xsl:apply-templates select='$investment-set[1]
</xsl:variable>
<xsl:variable name='other-nodes'>
<xsl:call-template name='total-investment'>
<xsl:with-param name='investment-set' select='$investment-set[po
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="number($first-node
</xsl:when>
<xsl:otherwise>0</xsl:othe
</xsl:choose>
</xsl:template>
<xsl:template match='investment' mode='investment-price'>
<xsl:value-of select='@units * @price'/>
</xsl:template>
</xsl:stylesheet>
XML Output
==========
<?xml version="1.0" encoding="UTF-8"?>
<table>
<tr>
<td>Joe Bloggs</td>
<td>39,219.50</td>
</tr>
</table>