RE: [xsl] unefficiate xpaths

Subject: RE: [xsl] unefficiate xpaths
From: "Martin Rowlinson \(MarrowSoft\)" <marrow@xxxxxxxxxxxxxx>
Date: Mon, 9 Jun 2003 22:12:02 +0100
Hi Corey,

> <xsl:for-each 
> select="//clients/client[count(commissions/commission[earnerId
> = //earners/earner[type = $rptType]/id]) = 0 and
website=$prodClass)]">

A couple of suggestions you could try...

1) get rid of the // wherever possible - if you know the actual paths
then use them.

2) the part "count(...) = 0" - as you're not really interested in the
count (i.e. how many there are) just whether none exist then use not()
around that part of the expresson, e.g.
  count(commissions/commission[earnerId = //earners/earner[type =
$rptType]/id]) = 0
becomes...
  not(commissions/commission[earnerId = //earners/earner[type =
$rptType]/id])

3) the part "//earners/earner[type = $rptType]/id" could be replaced
with a key (other parts could also be keyed).  For example...
  <xsl:key name="kEarnerType" match="earner" use="type"/>
and then...
  //earners/earner[type = $rptType]/id
becomes...
  key('kEarnerType',$rptType)/id

4) also "//earners/earner[type = $rptType]/id" does not need to know of
anything contextual of the main expression - so you could evaluate that
part once into a variable and then use the variable, e.g.
  <xsl:variable name="rptEarners"
select="key('kEarnerType',$rptType)/id"/>
and then use the $rptEarners variable.  By placing into a variable once
you avoid that part of the expression being re-evaluated for every node
outside the predicate.

5) when ANDing expressions always try to place the shortest evaluation
to the left (in case the transformation engine supports boolean short
circuiting).  I would imagine the "website = $prodClass" would be the
faster of the two ANDed parts in this case - so place that to the left.
To be sure there will be Boolean short circuiting you can always use
multiple predicates in place of ANDing (same effect).

6) although the "//clients/client[website=$prodClass]" could be keyed
anyway, e.g.
  <xsl:key name="kClientProdClass" match="client" use="website"/>
and then...
  select="key('kClientProdClass',$prodClass)"

Putting that all together you might end up with...

  <xsl:key name="kEarnerType" match="earner" use="type"/>
  <xsl:key name="kClientProdClass" match="client" use="website"/>
  ...
   <xsl:variable name="rptEarners"
select="key('kEarnerType',$rptType)/id"/>
   <xsl:for-each select="key('kClientProdClass',$prodClass)[not(
commissions/commission[earnerId = $rptEarners)]">

or something like that? ;)

Hope this helps
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator




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


Current Thread