Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to find table row having maximum number of table cell

Tags:

xslt

Hi I am using XSLT 1.0. My input looks like,

<table>
<tr>
  <td/>
  <td/>
  <td/>
</tr>
<tr>
  <td/>
  <td/>
  <td/>
</tr>
<tr>
  <td/>
  <td/>
  <td/>
  <td/>
</tr>
</table>

I want to know the maximum number of td in node. In this case, the maximum number of td is in 3rd tr and so my output should be 4. Need a template to do this. Thanks in advance

like image 671
vignesh Avatar asked Nov 17 '25 05:11

vignesh


2 Answers

Here is an example which does not use recursion. It just uses an xsl:for-each to loop through the TR elements, ordering by the number of TD elements in each. The first one is then the maximum.

The maximum is put in a variable, called maxCells which, as an example, is made an attribute of the table.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="/">
        <xsl:apply-templates select="table"/>
    </xsl:template>

    <xsl:template match="table">
        <!-- Variable holding the maximum number of cells in a row -->
        <xsl:variable name="maxCells">
            <xsl:for-each select="tr">
                <xsl:sort select="count(td)" order="descending"/>
                <xsl:if test="position() = 1">
                    <xsl:value-of select="count(td)"/>
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>

        <!-- Copy the table, adding the maximum cells as an attribute -->
        <xsl:copy>
            <xsl:attribute name="MaxCells">
                <xsl:value-of select="$maxCells"/>
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <!-- Identity Transform -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

When this stylesheet is applied to the provided table HTML above, the output is as follows:

<table MaxCells="4">
    <tr>
        <td/>
        <td/>
        <td/>
    </tr>
    <tr>
        <td/>
        <td/>
        <td/>
    </tr>
    <tr>
        <td/>
        <td/>
        <td/>
        <td/>
    </tr>
</table>
like image 87
Tim C Avatar answered Nov 18 '25 20:11

Tim C


I'd like to know if you are really trying to count cells or rather columns. What would you consider the correct result for the following table?

<table>
    <tr><td colspan="2"/><td/></tr>
    <tr><td/><td colspan="2"/></tr>
</table>

If you're just counting cells then you expect 2 - and that's what both previous answers provide. The table has actually three columns, however, so if that's what you're looking for (like when converting XHTML tables to CALS) you need to tweak @Tim C's solution a bit: replace count(td) with sum(td/@colspan) + count(td[not(@colspan)]) both in the <xsl:sort/> element and in the <xsl:value-of/>.

Unfortunately, even then the calculation fails to provide correct column counts in all cases. For example, it comes up with 2 instead of 3 when given this:

<table>
    <tr><td rowspan="2"/><td/></tr>
    <tr><td/><td/></tr>
</table>

I have no idea how to solve that one. I've never seen it in live data either (knock on wood).

One more thing. My karma is not sufficient to comment on @Tim C's answer but I need to write this lest I forget: the stylesheet is wrong in that it sorts the cell counts lexically (i.e. it thinks "120"<"19"<"5") so if you have a row with 5 cells and another one with 10 you will get 5 as maximum. This is easy to fix by adding data-type="number" to the <xsl:sort/> tag.

like image 25
codingjourney Avatar answered Nov 18 '25 21:11

codingjourney



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!