This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Finding the maximun number of nodes
- To: Dimitre Novatchev <dnovatchev at yahoo dot com>
- Subject: Re: [xsl] Finding the maximun number of nodes
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Fri, 5 Jan 2001 12:55:11 +0000
- CC: xsl-list at lists dot mulberrytech dot com
- Organization: Jeni Tennison Consulting Ltd
- References: <20010105114305.7918.qmail@web6303.mail.yahoo.com>
- Reply-To: xsl-list at lists dot mulberrytech dot com
Hi Dimitre,
Last time we had this problem arise on the list, Mike, David and
various others gave a good discussion about the efficiency of various
algorithms for getting these solutions. [The original question is at
http://www.biglist.com/lists/xsl-list/archives/200011/msg00006.html -
I'll leave you to follow the follow-ups.]
From what I learned from that discussion I think that the solution you
give, while simple, is likely to get increasingly worse the larger the
table gets. It goes once over each of the table rows; each time it
goes over a row, it goes over each of the other table rows once. That
means (I think) that it's an n^2 solution, and that for large tables
one of the solutions that I proffered (which are n(log n) or n(0)
solutions) is likely to be better. [I hope I got that right - no doubt
Mike or David will jump on me if not ;)]
Even given that, there are bits in the solution that you give that
will slow it down no matter the size of the table. I'd change it a bit
to make it more efficient.
First, the rows in the particular table don't change, so you can pull
that out as a variable and declare it up front:
<xsl:variable name="tableRows" select="//table[@ID='2']/tr" />
<xsl:for-each select="$tableRows">
<xsl:if test="count($tableRows[count(td) > count(current()/td)]) = 0">
<xsl:value-of select="count(td)"/>:
</xsl:if>
</xsl:for-each>
Second, within each run of the loop, the count of the current row's
cells isn't going to change, so it's best to pull that out as a
variable and test against that.
<xsl:variable name="tableRows" select="//table[@ID='2']/tr" />
<xsl:for-each select="$tableRows">
<xsl:variable name="rowColumns" select="count(td)" />
<xsl:if test="count($tableRows[count(td) > $rowColumns]) = 0">
<xsl:value-of select="count(td)"/>:
</xsl:if>
</xsl:for-each>
Finally, within a test, counting the number of nodes in a node set to
see if it's 0 is redundant: testing a node set returns true if there
are any nodes in the node set, false if not. So you can substitute
your test for a call to not() which is likely to be more efficient due
to processor optimisation:
<xsl:variable name="tableRows" select="//table[@ID='2']/tr" />
<xsl:for-each select="$tableRows">
<xsl:variable name="rowColumns" select="count(td)" />
<xsl:if test="not($tableRows[count(td) > $rowColumns])">
<xsl:value-of select="count(td)"/>:
</xsl:if>
</xsl:for-each>
Sorry if I'm being picky :)
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list