Dipesh,
As Markus said, since XSLT doesn't do "loops" in the commonly understood
sense, you can't perform a loop to find a maximum.
Ordinarily, in XSLT, if a problem appears which can *only* be solved by
looping, we use a recursive template (a template that calls itself) to
perform the loop.
There are other ways to find maxima, however, including a couple of tricks.
In your case, one of these is easy enough to use. Here's a way of using a
sorting instruction to assign to a variable a copy of the node in the
document with the most attributes (or rather, the first node of the set of
nodes with the most attributes):
<xsl:variable name="mostattributes">
<xsl:for-each select="/descendant::node()">
<xsl:sort select="count(attribute::*)"
order="descending" data-type="number"/>
<xsl:if test="position()=1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
Once we've done this, however, we run into another wrinkle (another reason
your problem is tough): we need to process this node. This introduces
another level of complexity, since XSLT 1.0 was designed not to allow
compound processing in this way (that is, processing not a node from the
input, but a node that has been generated by the stylesheet).
In such a case, one could consider "stretching" XSLT 1.0 by using an
extension function to convert the result-tree-fragment generated by this
routine (remember, it's a *copy* of the node in our source tree) into an
XSLT node set, which we could then process. Here, however, there's another
trick we can use to retrieve the actual node itself. Instead of copying the
node into our variable, we can simply assign to the variable a value that
identifies that node uniquely ... using this identifier to find our node.
An XSLT processor can assign and use a unique identifier to any node in the
input using the generate-id() function. So if we say, instead,
<xsl:variable name="mostattributes">
<xsl:for-each select="/descendant::node()">
<xsl:sort select="count(attribute::*)"
order="descending" data-type="number"/>
<xsl:if test="position()=1">
<xsl:value-of select="generate-id()"/><!-- this line has changed! -->
</xsl:if>
</xsl:for-each>
</xsl:variable>
we can then retrieve the actual node we are interested by querying the
document again, with an XPath predicate expression using our unique ID:
<xsl:variable name="mostattributes-node" select="//node()[generate-id() =
$mostattributes]"/>
I know this is a very roundabout way of getting what ought to be a simple
thing. It may comfort you to know (or maybe not) that this business of
finding minima and maxima and so forth is recognized as a weak area in XSLT
1.0 -- this is why you will find it addressed in the EXSLT set of extension
functions (see exslt.org), another thing you may want to investigate as you
become more expert in this technology.
I hope this helps --
Wendell
At 10:22 PM 8/21/2003, you wrote:
Thanks a lot for replying and corroborating that the problem is tough....
======================================================================
Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list