Re: [xsl] template precedence problem

Subject: Re: [xsl] template precedence problem
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 17 May 2002 10:04:10 +0100
Hi Ben,

> I'd really like to apply specific template matches like "Cost" in
> preference to my more generic "*[...]". However *[..] seems to take
> precedence over "Cost". If I change *[...] to * precendence occurs
> the way I'd like "Cost" is matched in preference to "*".
>
> The XLST programmers spec indicates that this is correct behaviour.
> Why does the xpath spec(?) allow more generic template matches to
> take higher priority?. Will this occur in XPATH 2.0? Can someone
> provide me with an xpath for my match *[..] that takes lower
> priority? I have sucessfully corrected this by setting the priority
> attribute on *[...] to a lower value. However I dislike doing this
> because it means every time I add a new template to my stylesheet I
> need to think about its priority in contrast the the prirorities
> I've forcibly adjusted.

Usually, providing a predicate means that you're making a more
specific match. For example:

  li[1]

is more specific than:

  li

I doubt that the prioritisation method will change in XSLT 2.0, but
remember that you can use the priority attribute to specifically
assign a lower (or higher) priority to certain templates. In your
case, you could do:

<xsl:template priority="-0.25"
  match="*[not(document('')//set:Sets/set:Set[@name='elementRules']
                 /set:Item[@name=name()])]">
...
</xsl:template>

To lower the priority of your "generic" template. (Or set the priority
as something higher than 0.5 on your more specific templates.)

By the way, are you sure that this match pattern is doing what you
think it's doing? It's matching any element, as long as there's a not
a set:Item within your stylesheet whose name attribute is 'set:Item'.
The name() function in the predicate is evaluated relative to the
set:Item element, not the matched element. I think that you want to
do:

<xsl:template priority="-1"
  match="*[not(document('')/*/set:Sets/set:Set[@name='elementRules']
                 /set:Item/@name = name())]">
...
</xsl:template>

Note that I replaced the document('')//set:Sets with
document('')/*/set:Sets, which will give much better performance
because it means that processor won't have to search through every
level of the entire stylesheet to find a set:Sets element.

Cheers,

Jeni

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


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


Current Thread