xsl-list
[Top] [All Lists]

Re: [xsl] A more concise way to handle empty numeric elements

2007-06-07 06:16:47
On 6/7/07, Mark Anderson <mark(_dot_)anderson(_at_)technique-group(_dot_)com> 
wrote:
Hi All

I have to process an XML file that contains a lot of numeric data. Many of the 
elements that have no value are empty instead of being zero and it may differ 
for each line, for example

<line id=1>
 <cost1>1000</cost1>
 <cost2>0</cost2> <!-- 0 here, but empty in next line -->
 <cost3></cost3>
</line>
<line id=2>
 <cost1>2000</cost1>
 <cost2></cost2>
 <cost3>3000</cost3>
</line>

I want to do:

<xsl:for-each select="line">
       <xsl:value-of select="format-number(cost1 + cost2 + cost3,'#,###')"/>
 </xsl:for-each>

However, the empty elements will cause "NaN" to be displayed

To fix it I can do:

<xsl:for-each select="line">
<xsl:variable name="cost1">
 <xsl:choose>
 <xsl:when test="(cost1 &gt;= 0)"><xsl:value-of select="cost1"/></xsl:when>
 <xsl:otherwise>0</xsl:otherwise>
 </xsl:choose>
</xsl:variable>
<xsl:variable name="cost2">
 <xsl:choose>
 <xsl:when test="(cost2 &gt;= 0)"><xsl:value-of select="cost2"/></xsl:when>
 <xsl:otherwise>0</xsl:otherwise>
 </xsl:choose>
</xsl:variable>
<xsl:variable name="cost3">
 <xsl:choose>
  <xsl:when test="(cost3 &gt;= 0)"><xsl:value-of select="cost3"/></xsl:when>
 <xsl:otherwise>0</xsl:otherwise>
 </xsl:choose>
</xsl:variable>
       <xsl:value-of select="format-number($cost1 + $cost2 + $cost3,'#,###')"/>
 </xsl:for-each>

However, it seems very long winded. Also the output is HTML, so it makes it 
hard to read the HTML with so much XML interwoven.

I realized I could write a template to return 0 for each empty element, but the 
call-template and parameter declaration will add further lines.

Is there a more succinct/elegant way to do it? (it's a shame "number(cost1)" 
doesn't return 0 for empty elements)

BTW: I'm using XSLT1.0 and can't use any extensions



hmmm it's a bit hacky but you can do:

<xsl:variable name="zero">0</xsl:variable>

<xsl:value-of select="(cost1/text()|$zero)[1] +
(cost2/text()|$zero)[1] + (cost3/text()|$zero)[1]"/>

hopefully someone else will have a better idea...

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--