Re: [xsl] How do you get the most recent element?

Subject: Re: [xsl] How do you get the most recent element?
From: Eric Vermetten <EVermetten@xxxxxxxxxxxxx>
Date: Sun, 11 Feb 2001 19:56:43 -0000
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() &gt; 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() &gt; 1]/time" >
         <xsl:variable name="p" select="position()" />

         <xsl:if test=". &lt; $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() &gt; 1]/time" >
         <xsl:variable name="p" select="position()" />

         <xsl:if test=". &lt; $notes[$p]/time">
            <xsl:if test="$p+1 &lt; 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


Current Thread