Re: [xsl] Find the node with maximum elements

Subject: Re: [xsl] Find the node with maximum elements
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sun, 04 Nov 2007 08:23:11 -0500
At 2007-11-04 18:15 +0530, Mukul Gandhi wrote:
The following solution is likely more efficient than Ken's (because,
it calculates 'max' only once):

Which is what I already indicated in my response:


At 2007-11-03 15:19 -0400, G. Ken Holman wrote:
You can optimize the speed by putting the max value into a variable and testing against that

But, Mukul, consider the following ... in your example, you are executing the <xsl:for-each> once for every car:


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

<xsl:output method="text" />

 <xsl:template match="/Sample">
   <xsl:variable name="max-count" select="max(*/count(Car))" />
   <xsl:for-each select="*">
     <xsl:if test="count(Car) = $max-count">
       <xsl:value-of select="local-name()" /><xsl:text> </xsl:text>
     </xsl:if>
   </xsl:for-each>
 </xsl:template>

</xsl:stylesheet>

If the original poster had followed my guidance of using the variable and my suggestion of using the predicate, it would not loop as much.


Or, thinking about it more ... why even use an <xsl:for-each>?

I hope the answer below illustrates the difference even more. If you don't worry about the variable then the entire solution can be written in a single instruction ... see the second stylesheet below.

Oh, as for optimization, I specifically chose to run the max() instruction on an address rooted at the top of the tree ... not on the current() function. I would think a processor could optimize the calculation of that result since the address never changes for the whole execution of the stylesheet. Mike's citation in his response was for an address with the shape max(current()/*/...) and not for the shape of the address max(/Sample/...) as I used in my original post.

So, since I'm giving an absolute XPath address, I would think this is an opportunity for optimization, so I'll stick then with the one-line second solution avaneesh2.xsl noted below as the briefest and fastest potential solution to the problem as originally posted.

I hope this helps.

. . . . . . . . . . Ken

T:\ftemp>type avaneesh.xml
<Sample>
    <Toyota>
          <Car>Camry</Car>
          <Car>Corrola</Car>
     </Toyota>
     <Honda>
            <Car>Accord></Car>
          <Car>Civic</Car>
          <Car>Pilot</Car>
     </Honda>
     <Mitsubishi>
        <Car>Lancer</Car>
        <Car>Lancer</Car>
        <Car>Lancer</Car>
     </Mitsubishi>
    <Hyundai>
        <Car>Sonata</Car>
        <Car>Accent</Car>
</Hyundai>
</Sample>

T:\ftemp>type avaneesh.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:variable name="max" select="max(/Sample/*/count(Car))"/>
  <xsl:value-of select="/Sample/*[count(Car)=$max]/name(.)"
                separator="&#xa;"/>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>xslt2 avaneesh.xml avaneesh.xsl con
Honda
Mitsubishi
T:\ftemp>type avaneesh2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:value-of select="/Sample/*[count(Car)=max(/Sample/*/count(Car))]
                        /name(.)"
                separator="&#xa;"/>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>xslt2 avaneesh.xml avaneesh2.xsl con
Honda
Mitsubishi
T:\ftemp>

--
Comprehensive in-depth XSLT2/XSL-FO1.1 classes: Austin TX,Jan-2008
World-wide corporate, govt. & user group XML, XSL and UBL training
RSS feeds:     publicly-available developer resources and training
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread