|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: First Element in Sorted List
On 6/2/05, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> >
> > My process needs to take action on the first element in a list of
> > elements where the logic to determine first is the lowest
> > numeric value
> > of the sortorder attribute. I don't believe there is a
> > one-line way to
> > do this - I believe the entire list must be sorted, and then the
> > position of each element after sort compared to determine if
> > it is first.
>
> Yes. Even in XSLT 2.0 this may be the best approach. 2.0 offers min/max
> functions, but they give you the highest/lowest value, not the node having
> that value.
>
> Writing a recursive template/function might give you better performance
than
> sorting (linear rather than n*log(n)).
>
> There is a one-line solution: $x[not($x/@sortorder < @sortorder)] but it's
> quite likely to have poor (quadratic) performance.
>
> You could consider using EXSLT math:highest() or math:lowest().
>
> Or I'm sure there's something in Dimitre's box of tricks called FXSL.
>
> Michael Kay
> http://www.saxonica.com/
The following FXSL one-liner does the job:
<xsl:sequence select=
"2*f:xsltSort(/*/*/@sortorder/xs:integer(.), f:add(0))[1]"/>
In this case, the "do-something" operation on the minimum item of the
sequence is double-it.
When evaluated against the following source xml:
<t>
<x sortorder="3"/>
<x sortorder="2"/>
<x sortorder="5"/>
<x sortorder="8"/>
<x sortorder="7"/>
<x sortorder="9"/>
<x sortorder="6"/>
<x sortorder="4"/>
<x sortorder="1"/>
<x sortorder="2"/>
</t>
The correct result:
2
is produced.
The f:xsltSort() function is simply a wrapper around the
xsl:perform-sort
instruction. It accepts a list of functions, which are composed to
produce the effect of multiple sort keys. Here's the code of the
function:
<xsl:function name="f:xsltSort" as="item()*">
<xsl:param name="pSeq" as="item()*"/>
<xsl:param name="pCriteria" as="node()*"/>
<xsl:perform-sort select="$pSeq">
<xsl:sort select="f:compose-flist($pCriteria, .)"/>
</xsl:perform-sort>
</xsl:function>
Certainly, in a future refinement I should also either process an
explicitly passed type-argument (e.g. number or text) or find a way to
efficiently determine the common most non-generic type of all items in
a sequence.
Any ideas?
--
Cheers,
Dimitre Novatchev
---------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all.
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








