Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Register | FAQ | Members List | Calendar | 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 tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developersí questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old December 1st, 2008, 03: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

Reply With Quote
  #2 (permalink)  
Old December 1st, 2008, 04: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,133
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 -/
Reply With Quote
  #3 (permalink)  
Old December 1st, 2008, 04:38 AM
mhkay's Avatar
Wrox Author
Points: 18,410, Level: 59
Points: 18,410, Level: 59 Points: 18,410, Level: 59 Points: 18,410, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,949
Thanks: 0
Thanked 289 Times in 284 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
Reply With Quote
  #4 (permalink)  
Old December 1st, 2008, 07: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!


Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off

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 11:13 AM
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



All times are GMT -4. The time now is 07:47 AM.


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.