Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

using XSLT, how to sum values that might be blank 1

Status
Not open for further replies.

ddiamond

Programmer
Apr 22, 2005
918
US
I am trying to sum a bunch of numeric values.

Code:
<xsl:value-of select="CommPropCov + ComGenCov + ProfLiabCov + TerrCov"/>
Only problem is that some of these values may be blank or missing. When this happens the result is 'NaN'. What I want to do is treat blank or missing values as zero. Any ideas?
 
The idea is NaN = NaN is evaluated to false. Hence, to ensure each element is of number format, you can make out a variable each for the component involved. Like this (for the two components only for brevity sake, obvious generalization to more components, like 4 instead of 2).
[tt]
[blue]<xsl:variable name="n_CommPropCov">
<xsl:choose>
<xsl:when test="number(CommProvCov) = number(CommPropCov)"><xsl:value-of select="number(CommPropCov)" /></xsl:when>
<xsl:when test="not(number(CommProvCov) = number(CommProvCov))">0</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="n_CommGenCov">
<xsl:choose>
<xsl:when test="number(CommGenCov) = number(CommGenCov)"><xsl:value-of select="number(CommGenCov)" /></xsl:when>
<xsl:when test="not(number(CommGenCov) = number(CommGenCov))">0</xsl:when>
</xsl:choose>
</xsl:variable>[/blue]
<xsl:value-of select="[blue]$[/blue]CommPropCov + [blue]$[/blue]ComGenCov" />
[/tt]
 
Amendment
The last line should sure be read like this.
[tt]<xsl:value-of select="$[red]n_[/red]CommPropCov + $[red]n_[/red]ComGenCov" />[/tt]
 
Thanks tsuji. Works perfectly. Here's my final solution:

<xsl:variable name="n_CommPropCov">
<xsl:choose>
<xsl:when test="number(CommProvCov)">
<xsl:value-of select="number(CommPropCov)" />
</xsl:when>
<xsl:eek:therwise>0</xsl:eek:therwise>
</xsl:choose>
</xsl:variable>

Notice I used the otherwise clause in place of your 2nd test clause. I also found that the condition test="number(CommProvCov)" had the same effect as test="number(CommProvCov) = number(CommPropCov)".
 
Thanks! It is as good if not better.
 
Here is a version that uses a named template to avoid duplicating code.
Code:
<xsl:template name="nvl">
  <xsl:param name="value" />
  <xsl:choose>
    <xsl:when test="number($value)">
      <xsl:value-of select="number($value)" />
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>
Code:
<xsl:variable name="n_CommPropCov">
  <xsl:call-template name ="nvl">
    <xsl:with-param name="value" select="CommPropCov" />
  </xsl:call-template>
</xsl:variable>
<xsl:variable name="n_ComGenCov">
  <xsl:call-template name ="nvl">
    <xsl:with-param name="value" select="ComGenCov" />
  </xsl:call-template>
</xsl:variable>
<xsl:variable name="n_ProfLiabCov">
  <xsl:call-template name ="nvl">
    <xsl:with-param name="value" select="ProfLiabCov" />
  </xsl:call-template>
</xsl:variable>
<xsl:variable name="n_TerrCov">
  <xsl:call-template name ="nvl">
    <xsl:with-param name="value" select="TerrCov" />
  </xsl:call-template>
</xsl:variable>
 
That's the way to go. Thanks for the dev!
 
An even easier solution:
Code:
<xsl:template name="sum">
  <xsl:param name="list" />
  <xsl:variable name="sum" select="sum($list[number(.)=number(.)])" />
  <xsl:choose>
    <xsl:when test="number($sum)">
      <xsl:value-of select="$sum" />
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>
Code:
<xsl:call-template name="sum">
  <xsl:with-param name="list"
    select="CommPropCov | ComGenCov | ProfLiabCov | TerrCov" />
</xsl:call-template>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top