[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Ordering of Blocks based on Input/Output

Subject: Re: Ordering of Blocks based on Input/Output
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 9 May 2001 15:09:27 +0100
match the blocks
Hi Francis,

> Quite right about the equivalence, though I don't know if doing
> count() on a node-set held in a variable will take as long as it
> would if gathering the node-set for the first time. Certainly
> "test='$todo'" is safer and better XSLT style.

It probably depends on whether the processor is lazy about evaluating
the variable. But of course a naive processor would still evaluate the
entirety of the $todo node set with that test, it's only an optimised
one that would know it could stop looking after one node. If you want
to 'assume no optimisation' (one of Mike Kay's tips) completely, then
really you should use test="$todo[1]".

Here's my crack at the problem, which is basically the same as yours
except that I'm applying templates and hence stepping through the
blocks one by one.

<!-- key to find the blocks that a block takes inputs from -->
<xsl:key name="inputs"
         use="../../input/@block" />

<xsl:template match="root">
      <!-- apply templates to the first block that doesn't have any
           inputs -->
            select="system/block[not(key('inputs', name))][1]" />

<xsl:template match="block">
   <xsl:param name="left"
              select="/root/system/block[count(.|current()) != 1]" />
   <xsl:copy-of select="." />
   <xsl:variable name="next"
                 select="$left[not(key('inputs', name) =
                                   $left/name)][1]" />
   <xsl:apply-templates select="$next">
      <xsl:with-param name="left"
                      select="$left[count(.|$next) != 1]" />

The two solutions *will* give different results in certain situations
because of the different strategies they use.

I really don't know about the relative performance of the two - Dan,
you'd have to try it out.  My instinct is that going through the nodes
one by one would cause less nodes to be visited overall - it may seem
more efficient to collect and process them all at the same time, but
the collection process involves visiting a lot of nodes that shouldn't
be processed - the more you can cut down on this, the better.

Something that might improve performance is to have a pre-process that
sorts the blocks according to how many inputs they have.

And actually, the templates in both could take advantage of the
set:difference() extension function, which would make clearer what was
going on, and would improve performance if it was implemented

<xsl:template match="block">
   <xsl:param name="left"
              select="set:difference(/root/system/block, .)" />
   <xsl:copy-of select="." />
   <xsl:variable name="next"
                 select="$left[not(key('inputs', name) =
                                   $left/name)][1]" />
   <xsl:apply-templates select="$next">
      <xsl:with-param name="left"
                      select="set:differenct($left, $next)" />



Jeni Tennison

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

Current Thread


Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
First Name
Last Name
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.