Re: [xsl] Finding the maximun number of nodes

Subject: Re: [xsl] Finding the maximun number of nodes
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 5 Jan 2001 12:55:11 +0000
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


Current Thread