RE: [xsl] How count the Table cell (Cals Table) using XSL

Subject: RE: [xsl] How count the Table cell (Cals Table) using XSL
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Mon, 10 Jul 2006 11:48:57 +0100
Firstly, sorry about the lack of a line number in this message. This is now
fixed. I'm always interested in hearing of errors that are missing this
information - they can only be fixed on a case-by-case basis. The error is
actually on line 18.

The error actually comes from the sum() function. Although your stylesheet
is running in 1.0 mode, which generally means that doing arithmetic on
non-numbers will result in NaN rather than an error, the sum() function is
an exception: it produces an error when one of the values being summed is
"", even in backwards compatibility mode.

However, I don't think that getting NaN as the output would help you much,
in fact you would be better changing the stylesheet to say version="2.0" to
take advantage of the stricter typechecking in XSLT 2.0, which would give
you better diagnostics for your errors.

Looking at your code for FindMaxStringLength, it will generate an empty <x>
element if the node-set

//tr[2]/th[$n] | //tr/td[$n]

is empty, but greater than zero.

At this point I'm not sure I understand the logic of your code to see why
this is happening - but there's doesn't seem to be anything in your code
that ensures it can't happen. You should probably test for this condition
and output 0 in this case.

Of course, your logic for finding the sum of the maxima of the
string-lengths can be greatly simplified if you take advantage of the fact
that you are using an XSLT 2.0 processor, which offers constructs such as:

sum(for $i in 1 to $N return max(//tr/td[$N]/string-length())

Michael Kay
http://www.saxonica.com/

 

> -----Original Message-----
> From: Byomokesh [mailto:bkesh@xxxxxxxxxxxxxxx] 
> Sent: 10 July 2006 10:32
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Cc: 'Mukul Gandhi'
> Subject: RE: [xsl] How count the Table cell (Cals Table) using XSL
> 
> Hi,
> 
> I tried many option, but did not found solution. Same 
> Validation Error showing. If I have convert one table, it can 
> easily converted. But If I have paste another table in same 
> file, then showing validation Error.
> 
> This Error is --
> =======================================================
> Validation error
>   FORG0001: Cannot convert string "" to a double 
> Transformation failed: Run-time errors were reported 
> =======================================================
> 
> 
> What is the reason?
> 
> This is my XML File
> --------------------
> 
> <p>Table 1.3 shows the relative FCC and IEEE power output 
> limits.</p> <table border="0" cellspacing="0" cellpadding="1" 
> width="90%"> <thead> <tr> <th valign="top" 
> colspan="9"><b>Table 1.1 802.11b Channels</b></th> </tr> <tr> 
> <th valign="top"><b>Channel Number</b></th> <th 
> valign="top"><b>Center Frequency (in GHz)</b></th> <th 
> valign="top"><b>USA</b></th> <th 
> valign="top"><b>Europe</b></th> <th 
> valign="top"><b>Spain</b></th> <th 
> valign="top"><b>France</b></th> <th 
> valign="top"><b>Israel</b></th> <th 
> valign="top"><b>China</b></th> <th 
> valign="top"><b>Japan</b></th> </tr> </thead> <tbody> <tr> 
> <td valign="top">1</td> <td valign="top">2.412</td> <td 
> valign="top">&#x2713;</td> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x00A0;</td> <td valign="top">&#x00A0;</td> <td 
> valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td> </tr> <tr><td valign="top">2</td> 
> <td valign="top">2.417</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">3</td> 
> <td valign="top">2.422</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">4</td> 
> <td valign="top">2.427</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">5</td> 
> <td valign="top">2.432</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">6</td> 
> <td valign="top">2.437</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">7</td> 
> <td valign="top">2.442</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">8</td> 
> <td valign="top">2.447</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">9</td> 
> <td valign="top">2.452</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">10</td> 
> <td valign="top">2.457</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">11</td> 
> <td valign="top">2.462</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x2713;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x2713;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">12</td> 
> <td valign="top">2.467</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">13</td> 
> <td valign="top">2.472</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x2713;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td 
> valign="top">&#x2713;</td></tr> <tr><td valign="top">14</td> 
> <td valign="top">2.484</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td valign="top">&#x00A0;</td> 
> <td valign="top">&#x00A0;</td> <td 
> valign="top">&#x2713;</td></tr> </tbody> </table> <p>more 
> columns</p> <table border="0" cellspacing="0" cellpadding="1" 
> width="90%"> <thead> <tr> <th valign="top"><b>Channel 
> Number</b></th> <th valign="top"><b>Center Frequency (in 
> GHz)</b></th> </tr> </thead> <tbody> <tr> <td 
> valign="top">36</td> <td valign="top">5.180</td> </tr> <tr> 
> <td valign="top">40</td> <td valign="top">5.200</td> </tr> 
> <tr> <td valign="top">44</td> <td valign="top">5.220</td> 
> </tr> <tr> <td valign="top">48</td> <td 
> valign="top">5.240</td> </tr> <tr> <td valign="top">52</td> 
> <td valign="top">5.260</td> </tr> <tr> <td 
> valign="top">56</td> <td valign="top">5.280</td> </tr> <tr> 
> <td valign="top">60</td> <td valign="top">5.300</td> </tr> 
> <tr> <td valign="top">64</td> <td valign="top">5.320</td> 
> </tr> <tr> <td valign="top">149</td> <td 
> valign="top">5.745</td> </tr> </tbody> </table>
> 
> XSL File:----
> --------------
> 
> <xsl:template match="table">
>       <table>
>         <table.html frame="void" width="100%" rules="groups"
> align="left" />
>         <xsl:variable name="rtf">
>            <xsl:call-template name="FindMaxStringLength">
>               <xsl:with-param name="n"
> select="count(//tr[5]/td|//tr[5]/th)" />
>            </xsl:call-template>
>         </xsl:variable>
> 
> 
>         <colgroup>
>           <xsl:for-each select="$rtf/x">
> 
> <col width="{format-number(((. div (sum(../*))) * 100),'##.##')}%"/>
>           </xsl:for-each>
>         </colgroup>
> 
>         <xsl:copy-of select="*" />
>       </table>
>    </xsl:template>
> 
> 
>    <xsl:template name="FindMaxStringLength">
>        <xsl:param name="n" />
>       <xsl:if test="$n &gt; 0">
>           <x>
> 	    <xsl:for-each select="//tr[2]/th[$n] | //tr/td[$n]">
>                <xsl:sort select="string-length(.)" 
> order="descending" />
>                <xsl:if test="position() = 1">
>                    <xsl:value-of select="string-length(.)" />
>                </xsl:if >
>             </xsl:for-each>
>           </x>
>           <xsl:call-template name="FindMaxStringLength">
>              <xsl:with-param name="n" select="$n - 1" />
>           </xsl:call-template>
>        </xsl:if>
> 
> </xsl:template>
> 
> 
> <xsl:template match="tr">
> <xsl:text>&#xa;</xsl:text><tr>
> <xsl:apply-templates/>
> </tr>
> </xsl:template>
> 
> <xsl:template match="td">
> <xsl:text>&#xa;</xsl:text><td>
> <xsl:apply-templates/>
> </td>
> </xsl:template>
> 
> <xsl:template match="th">
> <xsl:text>&#xa;</xsl:text><th>
> <xsl:apply-templates/>
> </th>
> </xsl:template>
> 
> <xsl:template match="thead">
> <xsl:text>&#xa;</xsl:text><thead>
> <xsl:apply-templates/>
> </thead>
> </xsl:template>
> 
> <xsl:template match="tbody">
> <xsl:text>&#xa;</xsl:text><tbody>
> <xsl:apply-templates/>
> </tbody>
> </xsl:template>
> 
> Thanks,
> 
> Byomkesh

Current Thread