This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: selecting only one among many matching nodes..
- To: Zeynep Gunal <z dot gunal at publitec dot vnu dot com>
- Subject: Re: [xsl] selecting only one among many matching nodes..
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Sun, 4 Mar 2001 12:28:15 +0000
- CC: "'xsl-list at lists dot mulberrytech dot com'" <xsl-list at lists dot mulberrytech dot com>
- Organization: Jeni Tennison Consulting Ltd
- References: <2A64666AC5E2D311AF8F00805F19CC3072F2CA@pubntex>
- Reply-To: xsl-list at lists dot mulberrytech dot com
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
element:
<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 < .)]
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="." />
</xsl:if>
</xsl:for-each>
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:choose>
<xsl:when test="count($nodes) = 1">
<xsl:value-of select="." />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="min-of-rest">
<xsl:call-template name="minimum">
<xsl:with-param name="nodes"
select="$nodes[position() != 1]" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="number($min-of-rest) < .">
<xsl:value-of select="$min-of-rest" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
I hope that helps,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list