|
|
 |
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 p2p Programmer to Programmer discussion community. This is a community of more than 40,000 computer programmers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining our free Wrox p2p community you can post your own programming questions and respond to other programmers’ questions. Registered users also don't have to see the ads that are displayed to guests. Registration is fast, simple and absolutely free so please, join today!
Join today and post to win prizes! Post more to increase your chances of being Wrox’s top poster of the month.
|
 |

December 1st, 2008, 04:52 AM
|
|
Registered User
|
|
Join Date: Dec 2008
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
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
|

December 1st, 2008, 05:02 AM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Location: Newcastle, , United Kingdom.
Posts: 1,359
Thanks: 0
Thanked 31 Times in 31 Posts
|
|
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 -/
|

December 1st, 2008, 05:38 AM
|
 |
Wrox Author
Points: 12,735, Level: 48 |
|
|
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 3,923
Thanks: 0
Thanked 82 Times in 80 Posts
|
|
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
|

December 1st, 2008, 08:14 AM
|
|
Registered User
|
|
Join Date: Dec 2008
Location: , , .
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
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!
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
 |