Wrox Programmer Forums
| Search | Today's Posts | Mark Forums Read
BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition ISBN: 978-0-470-19274-0
This is the forum to discuss the Wrox book XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition by Michael Kay; ISBN: 9780470192740
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition ISBN: 978-0-470-19274-0 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
  #1 (permalink)  
Old December 1st, 2008, 04:52 AM
asc asc is offline
Registered User
 
Join Date: Dec 2008
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default Question about template precedence

Hello I have just begun to play around with XSLT and I have a question about template matching precedence that I haven't been able to figure out myself. That is, I know how to solve this problem to get the desired result, but I since I'm in the "learning phase" I would like to know why the XSLT stylesheet below produces the result below.

The XML-file:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<cars>
    <car>
        <brand>BMW</brand>
        <type>335i</type>
    </car>
    <car>
        <brand>Audi</brand>
        <type>A4 3.0 TDI</type>
    </car>
    <car>
        <brand>Alfa</brand>
        <type>159 3.2 JTS V6</type>
    </car>
</cars>
The XSLT stylesheet:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="..."> 
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>

     <xsl:template match="/">
        <html>
          <body>
            [list]
              <xsl:apply-templates/>
            </ul>
          </body>
        </html>
      </xsl:template>


    <xsl:template match="*"/>


    <xsl:template match="//car[type='335i']">
        <li><xsl:value-of select='brand'/></li>  
    </xsl:template>

</xsl:stylesheet>
The output generated:
Code:
<html>
  <body>
    <ul /> 
  </body>
</html>
(1) The first thing I'm not quite sure about is if the last two templates are conflicting. Looking at the output it seems that way, but I would have expected, that a more specific match (like the car match) has higher precedence than a more general match (*). Could anyone comment on this?

(2) Under the assumption that the two templates are conflicting, I understand that it depends on the implementation of the XSLT processor if an error is reported or the last of the conflicting templates is chosen. Since my XSLT processor (= XMLSpy) does not report an error, the last matching template should be chosen.

So, in either case I would expect the following output, because
if the templates are conflicting, the third template should be chosen and thus "BMW" should be written to the destination tree and the other cars are not. If, on the other hand, the two templates are not conflicting, then "BMW" should be written to the destination tree by the third template and the other cars match the second template which does nothing.

Code:
<html>
  <body>
    [list]
      <li>BMW</li>
    </ul> 
  </body>
</html>
To summarize, my questions are
(1) Are the "<xsl:template match="*"/>" and "<xsl:template match="//car[type='335i']">" templates and conflicting?

(2) Why does the XSLT-script produce an empty list?

I really want to know what is happening here and hoping for your help ;)

Regards,
Alex

  #2 (permalink)  
Old December 1st, 2008, 05:02 AM
samjudson's Avatar
Friend of Wrox
Points: 8,687, Level: 40
Points: 8,687, Level: 40 Points: 8,687, Level: 40 Points: 8,687, Level: 40
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Aug 2007
Location: Newcastle, , United Kingdom.
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

Your root template matches the root of the document, then tells the stylesheet to apply templates to all irs children.

The first child, the "cars" node, is then matched, on the second template. This template tells it to do nothing else, so that's what it does. No other nodes are therefore being processed.

Change <xsl:template match="*"/> to <xsl:template match="text()"/> - this will probably give you the output you want.

/- Sam Judson : Wrox Technical Editor -/
  #3 (permalink)  
Old December 1st, 2008, 05:38 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Yes, they are conflicting, because an element that matches //car[...] will also match "*".

The default priority of a template depends on the syntax of the match pattern. The pattern "*" has lower priority than "//car[...]". So in this case the second will always be chosen (assuming it matches).

Your stylesheet produces no output because the template for the document node applies templates to the top-level element (<cars>), and the template rule that matches <cars> is the one with match="*", which doesn't apply-templates to its children.

Incidentally, you don't need "//" at the start of a match pattern. Its only effects are subtle things you almost certainly don't want: (a) it can change the default priority of the template in unexpected ways, and (b) it will only match the car element if the element is part of a document. Just write match="car[type='555i']"

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
  #4 (permalink)  
Old December 1st, 2008, 08:14 AM
asc asc is offline
Registered User
 
Join Date: Dec 2008
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Ah, I understand. I was thinking that 'match="/"' matches the top-level element of of the document, but it really means the document root which is not the same as the top level element.

Thank you very much!




Similar Threads
Thread Thread Starter Forum Replies Last Post
Question on Apply Template vvenk XSLT 7 July 10th, 2008 12:21 PM
anyway to call a template with a lower precedence? ojasrege XSLT 3 November 30th, 2007 12:13 PM
Datagrid Item Template question dparsons ASP.NET 1.0 and 1.1 Professional 3 March 14th, 2007 09:08 AM
Template Column - question vox ASP.NET 1.0 and 1.1 Basics 2 June 7th, 2005 11:53 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.