Re: [xsl] Template priority

Subject: Re: [xsl] Template priority
From: Peter Davis <pdavis152@xxxxxxxxx>
Date: Mon, 17 Jun 2002 22:19:47 -0700
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Monday 17 June 2002 19:34, Brian Grainger wrote:
> <root>
>    <x>
>      <z bunny="bugs farmer="fudd"/>
>    </x>
>    <y>
>      <z birdy="tweety" puddytat="sylvester"/>
>    </y>
> </root>
>
> What would be the recommended way to differentiate the two templates?
> Parentage?

Since the most discernable difference between the to <z>'s is the two 
different parents (<x> and <y>), you should use that as a constraint in the 
template's match attribute:

<xsl:template match="x/z">
  I live in a hole and have often kissed Elmer on the lips.
</xsl:template>

<xsl:template match="y/z">
  I live in a cage and talk with a lisp.
</xsl:template>

Think of the nodes listed in the templates' match attributes as being 
processed in reverse.  When the XSLT processor encounters a <z> element, it 
will select all templates that are capable of matching a <z> (the two above).  
Then it will try to narrow down the choice, which in this case means it will 
look at what precedes the "z" in the match expression: an "x/" or a "y/".  
This means the two templates above will match a <z> who's parent is an <x>, 
or a <z> who's parent is a <y>.  Neither template will match the same <z> as 
the other, which is, I think, what you want.  You could also restrict 
matching by testing the presence of attributes or children, but testing for 
the parent is easier and more efficient.

> Mode?

You could also solve the problem using modes.  Modes are generally used only 
when you want to use different templates for the same element in different 
situations, where "same" in this case would be defined as two elements with 
the same name, "z".  In your example, you do indeed have two different 
situations: when the parent is <x>, and when the parent is <y>.

Since you have to specify the mode in your <xsl:apply-templates mode="..."/>, 
that means you have to know which mode you are going to use beforehand.  If 
you have two templates that match <x> and <y> separately, then you can also 
separate the <xsl:apply-templates/> and specify the modes separately:

<xsl:template match="x">
  <xsl:apply-templates mode="parent-is-x"/>
</xsl:template>

<xsl:template match="y">
  <xsl:apply-templates mode="parent-is-y"/>
</xsl:template>

<xsl:template match="z" priority="1" mode="parent-is-x">
  I live in a hole and have often kissed Elmer on the lips.
</xsl:template>

<xsl:template match="z" priority="1" mode="parent-is-y">
  I live in a cage and talk with a lisp.
</xsl:template>

<!-- for nodes that are not <z/>, use the normal templates without a mode.   
The use of priorities helps form the "not a <z/>" conditional. -->

<xsl:template match="node()" priority="0" mode="parent-is-x">
  <xsl:apply-templates select="."/>
</xsl:template>

<xsl:template match="node()" priority="0" mode="parent-is-y">
  <xsl:apply-templates select="."/>
</xsl:template>

As you can see, this is a lot more complicated than matching parents, and it 
effectively does the same thing (that is, match the parents).

> Priority?

Priorities are used when you have multiple templates that are capable of 
matching a given node and you want to specify which of templates will be 
processed, since only one template can be processed at a time.  This is 
generally only useful if one template matches a superset of the nodes that 
can be matched by another, as I had to do in the previous two templates, 
where "node()" matches a superset of "z".  However, priorities alone cannot 
solve your problem.

Hope that helps!

- -- 
Peter Davis
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQE9DsLzNSZCJx7tYycRAvhXAJ9KvM/sT6wO5AEt6UFL/GdSWj9hQwCcCpre
3zdIaPqetJ12FXrP38g3O0k=
=Ap1E
-----END PGP SIGNATURE-----


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


Current Thread