This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Re: Re: Node Selection


Dimitre Novatchev wrote:
>> > I am using Xalan for xsl transformations. I have some xml with
>> > multiple <Activity> nodes in it for each part that is processed. The
>> > activity nodes are not sorted in any way in the xml. I want to
>> > select only the latest activity (by Date, Time) to process in the
>> > transform for my output to show the last activity scan on this part
>> > and ignore all other activity scans.
>> 
>> The easiest way to do this is to sort the Activity elements by their
>> Date and Time (in descending order), and then choose the first one
>> only to go on and process:
[snip]
>
> This is one of the most inefficient ways to find a maximum and Jeni
> must know it. In case there are thousands of nodes to be sorted, the
> unnecessary wait will be due exactly to following such an advice.

Well I did say *easiest* rather than *most efficient* ;)

Jim, if you have lots of Activity elements and find that your
transformation is unacceptably slow, then you could alternatively
use a recursive template.  This finds the next following Activity that
occurs after this one, and if there is one then applies templates to
it in 'latest' mode, and so on recursively through the Activity
elements.  If there isn't one, it applies templates to the Activity so
you can go on and process it.

<xsl:template match="Activity" mode="latest">
   <xsl:variable name="date-time" select="concat(Date, Time)" />
   <xsl:variable name="next"
                 select="following-sibling::Activity
                            [concat(Date, Time) > $date-time][1]" />
   <xsl:choose>
      <xsl:when test="$next">
         <xsl:apply-templates select="$next" mode="latest" />
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="." />
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

To kick this process off, you need to apply templates to the first
Activity element in your Part, in 'latest' mode:

<xsl:template match="Part">
   <xsl:apply-templates select="Activity[1]" mode="latest" />
</xsl:template>

[Caveat: this template will involve very deep recursion, which might
still be a problem on some processors (including Xalan, I believe), if
you're unlucky with the ordering of your Activity elements. It also
assumes that processors are smart enough to optimise XPath expressions
that end in a [1] predicate, and to therefore stop when they find the
first node in the path, but that shouldn't be a problem in Xalan.]

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]