Improve company productivity with a Business Account.Sign Up

x
?
Solved

xslt + NaN

Posted on 2002-03-25
4
Medium Priority
?
7,064 Views
Last Modified: 2013-11-18
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-microsoft-com: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="palantir">
  <![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[position()!=1]'/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select='palantir:Format(number(number($first-node) + number($other-nodes)))'/>
        </xsl:when>
        <xsl:otherwise>0</xsl:otherwise>
    </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.
0
Comment
Question by:cmain
  • 3
4 Comments
 
LVL 23

Expert Comment

by:b1xml2
ID: 6895283

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,'#,###,##0.00')" /></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[position()!=1]'/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="number($first-node) + number($other-nodes)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</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>
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 6895652
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-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<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="total-list">
<xsl:for-each select="descendant::investment">
<sum><xsl:value-of select="@units * @price" /></sum>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="sum" select="sum(msxsl:node-set($total-list)/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>
0
 
LVL 23

Accepted Solution

by:
b1xml2 earned 1200 total points
ID: 6895655
Notes
=====
This XSLT Document allows for multiple clients and for which there is proper totalling, it allows works for singular clients, hence to make the code run properly, you change the first template:

<xsl:template match="/">
<table><xsl:apply-templates select="//client" /></table>
</xsl:template>
0
 
LVL 1

Author Comment

by:cmain
ID: 6895751
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.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

585 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question