Re: [xsl] selecting only one among many matching nodes..

Subject: Re: [xsl] selecting only one among many matching nodes..
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sun, 4 Mar 2001 12:28:15 +0000
Hi Zeynep,

> I need to find the smallest 'ret' value where:
> AAA/code = AAA/CCC/code         and
> AAA/BBB/str1 = AAA/CCC/DDD/str1 and
> AAA/BBB/str2 = AAA/CCC/DDD/str2 and 
> AAA/BBB/str3 = AAA/CCC/DDD/str3
> which is here 3.

It looks as though the first step is to identify all the ret elements
elements that match the code and the str1, str2 and str3 of the BBB

<xsl:variable name="rets"
              select="AAA/CCC[code = /AAA/code and
                              DDD/str1 = /AAA/BBB/str1 and
                              DDD/str2 = /AAA/BBB/str2 and
                              DDD/str3 = /AAA/BBB/str3]/ret" />

When you have those, you need to find those nodes in $rets such that
there are no other nodes in $rets whose value is lower that that one:

  $rets[not($rets &lt; .)]

That's a fairly inefficient solution if you've got lots of nodes in
$rets.  Another method is to iterate over them, sorting by ascending
size, and then get the first one from the sorted list:

  <xsl:for-each select="$rets">
     <xsl:sort select="." data-type="number" />
     <xsl:if test="position() = 1">
        <xsl:value-of select="." />

If you're really worried about performance, then a recursive solution
would be best, something like:

<xsl:template name="minimum">
   <xsl:param name="nodes" />
      <xsl:when test="count($nodes) = 1">
         <xsl:value-of select="." />
         <xsl:variable name="min-of-rest">
            <xsl:call-template name="minimum">
               <xsl:with-param name="nodes"
                               select="$nodes[position() != 1]" />
            <xsl:when test="number($min-of-rest) &lt; .">
               <xsl:value-of select="$min-of-rest" />
               <xsl:value-of select="." />

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread