Re: [xsl] apply-templates and predicates

Subject: Re: [xsl] apply-templates and predicates
From: David Carlisle <davidc@xxxxxxxxx>
Date: Wed, 27 Apr 2005 14:25:46 +0100
   when applying templates it is possible to filter out unwanted nodes in a 
  number of ways, one is by putting a predicate on the apply-templates command 
  and use modes if you have more than one filter. Another is to 
  apply-templates to all nodes and put a predicate on the template match - 
  this avoids the use of modes.

I agree with the fact that there are two styles, although not with the
comment about modes. The use or not of modes is orthogonal to this
stylistic question. If you need to process the same template in two
different ways you can use modes to achieve that, whichever style you
are using.

  It improves efficiency i.e. the processor will only begin searching for 
  relevant elements rather than searching for matches which are then filtered 
  out immediately.

That's not at all clear (I suspect it's often false). It would also
depend on the implementation and the exact filter that you are using.

if for example you want all nodes to be processed except a b c and d
then you can do

<xsl:apply-templates select="node()[not(self::a or self::b or self::c or self::d)]"/>

or you can do

<xsl:template match="a|b|c|d"/>

My understanding (from comments made by MK on this list rather than
looking at the source) is that in the latter case the implemenation
probably uses some kind of hash table lookup to quickly find relevant
matches (the set of possible match patterns is known at compile time)
so in particular the lookup speed is probably not affected by the
length of the list of special cases.

In the former case the system (I would guess) really does a test against
each clause in the or expression (until the result of the predicate is
known) so here the time will increase linearly with the length of the
expression, it will also probably have to do this test against text nodes
as well as element nodes unless the optimiser was smart enough to change
it to
text()|*[not(self::a or self::b or self::c or self::d)]

  improves the readability of the stylesheet. The author will know 
  definitively which template is being invoked without having to look through 
  imported and included stylesheets.

I would say readability (and flexibility) is increased in the second
form (which is its main advantage) Look at the two forms above, reading
(by eye) a long Xpath filter expression can soon get hard compared to 
just looking at the match templates for each element to see what they do.
If as the stylesheet develops youneed to change teh set of elements that
are filtered or decide you want to make them issue a <xsl:message
warning rather than silently being discarded, it is much easier to
change the empty template  to a non-empty one than modify the filters.

  In a situation of no suitable match being found the inbuilt <xsl:template 
  match="*"> template will be invoked if it hasnt been overridden which could 
  lead to either unexpected or unnecessary searching.

I don't follow this comment, in both cases you are using apply-templates
so the default template will be invoked if teher is no more specific


This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:

Current Thread