codetoad.com
  ASP Shopping CartForum & BBS
  - all for $20 from CodeToad Plus!
  
  Home || ASP | ASP.Net | C++/C# | DHTML | HTML | Java | Javascript | Perl | VB | XML || CodeToad Plus! || Forums || RAM 
Search Site:



Previous Page  Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Page 7  Page 9 Page 10 Page 11 Next Page  

Resolving Conflicts Between Templates

Whenever you have rules in a language, such as rules in CSS or templates in XSLT, you need some way to resolve conflicts when two of the rules apply to the same situation. What would happen, for example, if you had one template that matched all <Character> elements and another template that matched only those <Character> elements that had <CastMember> as their parent:

 

<xsl:template match="Character">

<span class="character"><xsl:apply-templates /></span>

</xsl:template>

 

<xsl:template match="CastMember/Character">

<span class="character"><xsl:apply-templates select="Name" /></span>

</xsl:template>

 

A <Character> element in a <Description> element only matches one of the templates, because it doesn't have a <CastMember> element as its parent, so obviously the XSLT processor uses that template with it. But what about a <Character> element in a <CastMember> element? It matches both of the template's patterns, so what should the XSLT processor do?

Template Priority

Well, the XSLT processor will only ever process one template when you apply templates to a node, so it has to choose between the two templates that it's presented with in some way. It does this by looking at the template's priority. A template with a high priority is chosen over a template with a lower priority.

 

You can specifically assign a template a priority using the priority attribute on the <xsl:template> element. The priority attribute can be set to any number, including decimal and negative numbers. For example, you can give the two templates different specific priorities, as follows:

 

<xsl:template match="Character" priority="-1">

<span class="character"><xsl:apply-templates /></span>

</xsl:template>

 

<xsl:template match="CastMember/Character" priority="2">

<span class="character"><xsl:apply-templates select="Name" /></span>

</xsl:template>

Default Priorities

However, it would be very difficult to assign and keep track of priorities if the priority attribute was your only option. If you don't specify a priority attribute on a template, the XSLT processor assigns it a priority based on how specific its match pattern is. XSLT processors recognize three levels of priority in patterns:

 

        Patterns that match a class of nodes, such as *, which matches all elements, are assigned an implicit priority of -0.5

        Patterns that match nodes according to their name, such as Character, which matches <Character> elements, are assigned an implicit priority of 0


 

        Patterns that match nodes according to their context, such as CastMember/Character, which matches <Character> elements whose parent is a <CastMember> element, are assigned an implicit priority of 0.5

 

When assigning priorities based on patterns, it doesn't matter how specific the context information is: if you specify any context for a node then the template has a priority of 0.5. For example, Description/Link/Character has exactly the same priority as Description//Character.

 

Technically, it's an error if you have two templates that match the same node and the match patterns for the two templates have the same specificity. However, most processors recover from the error and use the template that you've defined last in the stylesheet. You should try to avoid having templates that have the same priority and can feasibly match the same node; use the priority attribute to assign them specific, different priorities.

If two templates match the same node, the processor uses the one with the highest priority. Priority can be assigned explicitly with the priority attribute or determined implicitly from the template's match pattern. As a last resort, the processor can select the last matching template in the stylesheet.

Currently, the templates that our stylesheet contains don't have any conflicts with each other because each of them only matches elements in a fairly specific context. To try out priorities, let's try making some of the templates conflict by removing some of that context information from one of them. For example, in TVGuide11.xsl, let's change the template that matches <Program> elements within <Description> elements to match any <Program> element:

 

<xsl:template match="Program">

<span class="program"><xsl:apply-templates /></span>

</xsl:template>

 

Now a <Program> element will always be matched by this template, and if it's a child of a <Channel> element then it will also match the following template:

 

<xsl:template match="Channel/Program">

<div>

<p>

<span class="date"><xsl:apply-templates select="Start" /></span>

<br />

<xsl:apply-templates select="Series" />

<br />

<xsl:apply-templates select="Description" />

<span onclick="toggle({Series}Cast);">[Cast]</span>

</p>

<div id="{Series}Cast" style="display: none;">

<ul class="castlist">

<xsl:apply-templates select="CastList/CastMember" />


 

</ul>

</div>

</div>

</xsl:template>

 

However, if you run TVGuide11.xsl with TVGuide3.xml, it won't make any difference to the result because the latter template, matching <Program> element children of <Channel> elements, has a higher priority. When the <Program> element that the XSLT processor is trying to process is a child of a <Channel> element, it will use the latter template, with the match pattern of Channel/Program; when it's not (such as when it's a child of a <Description> element), the processor will use the former template, with the match pattern of Program.

 

But we can change that in two ways. First, we can assign different priorities to the two templates using the priority attribute. Assign the general template a priority of 1, to create TVGuide12.xsl:

 

<xsl:template match="Program" priority="1">

<span class="program"><xsl:apply-templates /></span>

</xsl:template>

 

This explicit priority is higher than the implicit priority of the second template. If you run TVGuide12.xsl with TVGuide3.xml, you get the following mess:

 

 

Some of the formatting is still present because the elements inside the <Program> element still get processed by this template. However, the parts of the result that were generated by the second template, such as the <div> and <p> elements, are no longer present. You can get the same effect by removing the priority on the template matching all <Program> elements and giving the template matching <Program> elements within <Channel> elements a priority lower than -0.5.


 

A second way of manipulating the priority of the templates is to remove the context from the path for the second template (and remove the priority attributes that you just added), so the template that's supposed to be used to process <Program> elements within <Channel> elements looks like:

 

<xsl:template match="Program">

<div>

<p>

<span class="date"><xsl:apply-templates select="Start" /></span>

<br />

<xsl:apply-templates select="Series" />

<br />

<xsl:apply-templates select="Description" />

<span onclick="toggle({Series}Cast);">[Cast]</span>

</p>

<div id="{Series}Cast" style="display: none;">

<ul class="castlist">

<xsl:apply-templates select="CastList/CastMember" />

</ul>

</div>

</div>

</xsl:template>

 

Now the templates both apply to the same <Program> elements and have the same priority, which is an error. Move the template that's supposed to be for <Program> elements within <Description> elements below the above in the stylesheet (if it's not there already), to give TVGuide13.xsl. Most likely your processor will use the lower template in the stylesheet to process the <Program> elements, and you'll get the same mess as when you changed the priority explicitly. Processors are within their rights to terminate the stylesheet and give you an error, though, and some processors might warn you that there are two templates that match the same node with the same priority. Saxon, for example, gives reams of recoverable error messages, though it produces the result perfectly well:

 


 

It's often simpler to make templates whose match patterns don't include any information about the ancestry of the element, and it's easier for the processor too, because it doesn't have to check. For our TV guide stylesheet, we could adopt one of two styles to deal with elements that need to be treated differently in different places add ancestry information for those templates that deal with elements in the descriptions, or add ancestry information to the other templates, those that deal with the bulk of the result. I think it makes more sense to keep ancestry information on the templates that deal with descriptions, because that way it's easy to tell which templates are those that deal with descriptions and which aren't. TVGuide14.xsl shows the result of doing that.

Previous Page  Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Page 7  Page 9 Page 10 Page 11 Next Page  




Click here to Buy!

Buy Beginning XSLT here

© Copyright 2002 Wrox Press This chapter is written by Jeni Tennison and taken from "Beginning XSLT" published by Wrox Press Limited in June 2002; ISBN 1861005946; copyright Wrox Press Limited 2002; all rights reserved.

No part of these chapters may be reproduced, stored in a retrieval system or transmitted in any form or by any means -- electronic, electrostatic, mechanical, photocopying, recording or otherwise -- without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews.











Recent Forum Threads
• Global.Mapper.v15.2.3.b060614
• Geometric_Glovius_Pro_v3.6.1
• VERO.SurfCAM.v2014
• Schlumberger.Petrel.V2013.2
• Petrel.V2013.2
• Altair.HyperWorks.v12
• VoluMill.v6.1
• VoluMill.NEXION.6
• VERO.SurfCAM.v2014


Recent Articles
ASP GetTempName
Decode and Encode UTF-8
ASP GetFile
ASP FolderExists
ASP FileExists
ASP OpenTextFile
ASP FilesystemObject
ASP CreateFolder
ASP CreateTextFile
Javascript Get Selected Text


© Copyright codetoad.com 2001-2014