Hi. I have an XML file with a lot of numbers and am generating HTML
tables. I am probably backleveled with LotusXSL and XML4J, but just
downloaded xerces 1.1.0 (with xalan.jar) and seem to get the same results.
I only know very basic XSLT so I'm hoping someone can suggest some
improvements.
One of my problems is the input elements may contain a number, may be blank
or null, or may contain text such as "N/A". What I want to do is format
the number if it is a number, otherwise print the trimmed text, or generate
" " for an empty cell. My approach was as follows:
(part of the XML:)
<SR> 545000</SR>
<SP> 49.37</SP>
<SR> 437971</SR>
<SP> 37.00</SP>
.... (102 pairs of <SR> and <SP>)
(part of the XSL:)
<xsl:variable name="SR1" select="normalize-space(SR[1])"/>
<xsl:variable name="SR2" select="normalize-space(SR[2])"/>
...
<xsl:variable name="SP1" select="normalize-space(SP[1])"/>
<xsl:variable name="SP2" select="normalize-space(SP[2])"/>
...
<td align="right"> <xsl:if test="boolean(number($SR1))"><xsl:value-of
select="format-number($SR1,'###,###,##0')"/></xsl:if></td>
<td align="center"> <xsl:if test="boolean(number($SP1))"><xsl:value-of
select="format-number($SP1,'##0.00')"/></xsl:if></td>
<td align="right"> <xsl:if test="boolean(number($SR2))"><xsl:value-of
select="format-number($SR2,'###,###,##0')"/></xsl:if></td>
<td align="center"> <xsl:if test="boolean(number($SP2))"><xsl:value-of
select="format-number($SP2,'##0.00')"/></xsl:if></td>
(etc)
I used "boolean(number())" to ensure only numbers would be formatted,
otherwise the " " remains to give me an empty cell. Two problems:
non-numeric text is lost, and elements containing "0" are not formatted
because boolean() returns false if the number is zero.
The following will print non-numeric text but not the zero, but it's a lot
of lines for each element:
<td>
<xsl:choose>
<xsl:when test="boolean(number($SP1))"><xsl:value-of
select="format-number($SP1,'###,###,##0')"/></xsl:when>
<xsl:otherwise> <xsl:value-of select="$SP1"/></xsl:otherwise>
</xsl:choose>
</td>
I also tried adding 1 to the number(), this time resetting the variable,
hoping boolean() would return true for any number except -1, but this
didn't work:
<xsl:variable name="SR1" select="normalize-space(SR[1])"/>
<xsl:if test="boolean(number($SR1)+1)"><xsl:variable name="SR1"
select="format-number($SR1,'###,###,##0')"/></xsl:if>
...
<td align="center"> <xsl:value-of select="$SP1"/></td>
Another problem is it takes a long time to process. I used the SR[n]
approach so my table layout would be unaffected by an incorrect number of
input elements, but I imagine this adds a lot of overhead. I can't process
all <SR> elements first and then all <SP> elements, as I need to maintain
the pairing in the output. Is it better to call a template, for example to
process the above <choose> block for each element, or better to repeat the
block inline hundreds of times?
Thanks for any suggestions.
Nick Ridout
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list