This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: How do you get the most recent element?
- To: "'xsl-list-digest at lists dot mulberrytech dot com'" <xsl-list-digest at lists dot mulberrytech dot com>
- Subject: Re: [xsl] How do you get the most recent element?
- From: Eric Vermetten <EVermetten at nl dot alpnet dot com>
- Date: Sun, 11 Feb 2001 19:56:43 -0000
- Reply-To: xsl-list at lists dot mulberrytech dot com
David Carlisle wrote:
>For large data sets it may be better to use a recursive template to
>find the minimum entry in O(n) time rather than use xsl:sort which is
>likely to be O(n log n) (depending on how well your processor treats
>recursive calls, see an earlier long thread on this)
Recursing can be a way of living, and it feels fine to me.
However, there are alternatives. In the following
sorting is avoided. I think this is O(N), but there may be
hidden costs involved with the call of node-set(). When using
the latter, overhead certainly exists for the creation of the pos elements.
But then again, you can so easily get to the last of all those pos'ses
to finally get the position of the most recent note. [most-recent1]
Also I don't know the costs of
<xsl:for-each select="$notes[position() > 1]/time" >
I guess this can be optimized by an XSLT processor quite easily.
For most-recent2 there's some attention needed as to the maximum
number of digit positions ( of the position of the most-recent note).
This is because adressing the running string
(build by <xsl:value-of select="$p + 1" />) will only succeed if
every position encoded into this string takes same number of characters.
I'd appreciate comments on execution costs as to implementation
details, though for Saxon I'd expect that nothing will beat the
saxon:highest() extension function...
enjoy,
Eric
<!--+++++++++___i.xml___+++++++++++-->
<?xml version="1.0"?>
<wrap>
<note>
<time>4</time>
<content>c4</content>
</note>
<note>
<time>5</time>
<content>c5</content>
</note>
<note>
<time>2</time>
<content>c2</content>
</note>
<note>
<time>6</time>
<content>c6</content>
</note>
</wrap>
<!--+++++++++___i.xsl___+++++++++++-->
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:xalan="org.apache.xalan.xslt.extensions.Nodeset"
xmlns:saxon="http://icl.com/saxon"
extension-element-prefixes="xalan saxon"
exclude-result-prefixes="msxml xalan saxon"
version="1.0">
<?info use xalan:nodeset() or msxml:node-set() or saxon:node-set() ?>
<xsl:output method="html" />
<xsl:template name="most-recent1"><?expl with node-sets ?>
<xsl:param name="notes" />
<xsl:variable name="result">
<xsl:element name="pos"><xsl:value-of select="1" /></xsl:element>
<xsl:for-each select="$notes[position() > 1]/time" >
<xsl:variable name="p" select="position()" />
<xsl:if test=". < $notes[$p]/time">
<xsl:element name="pos">
<xsl:value-of select="$p + 1" />
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="xalan:nodeset($result)/pos[last()]" />
</xsl:template>
<xsl:template name="most-recent2"><?expl without node-sets ?>
<xsl:param name="notes" />
<xsl:variable name="result">
<xsl:value-of select="'01'" />
<?expl max position of most recent note must be less than 100 ?>
<xsl:for-each select="$notes[position() > 1]/time" >
<xsl:variable name="p" select="position()" />
<xsl:if test=". < $notes[$p]/time">
<xsl:if test="$p+1 < 10">
<xsl:value-of select="'0'" />
</xsl:if>
<xsl:value-of select="$p + 1" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="number(substring($result, string-length($result) -
1))" />
</xsl:template>
<xsl:template match="/">
<xsl:variable name="pos">
<xsl:call-template name="most-recent1"><?expl choose a postfix 1 or 2
?>
<xsl:with-param name="notes" select="//note" />
</xsl:call-template>
</xsl:variable>
<xsl:element name="w">
<xsl:copy-of select="//note[position() = $pos]" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list