Look at the XSLT-code under the address http://www.w3schools.com/xml/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog_apply ... Below you find the first part of this code (and the one decisive for my question):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
If you now change only the line
<xsl:apply-templates/>
to
<xsl:apply-templates select="cd"/>
the transformation does not work anymore ... (The code now looks as follows:)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates select="cd"/> <!--ONLY LINE OF CODE THAT WAS CHANGED-->
</body>
</html>
</xsl:template>
My question is: Why does the change break the code? In my opinion, the logic is the same in both cases:
UPDATE:
The whole xslt code is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
<xsl:template match="title">
Title: <span style="color:#ff0000">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
<xsl:template match="artist">
Artist: <span style="color:#00ff00">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
</xsl:stylesheet>
Here's an excerpt from the xml:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
......
</catalog>
What W3C schools doesn't tell you is about XSLT's Built-in Template Rules.
When you do <xsl:apply-templates select="cd"/>
you are positioned on the document node, which is the parent of the catalog
element. Doing select="cd"
will select nothing, because cd
is a child of the catalog
element, and not a child of the document node itself. Only catalog
is a child.
(Note that catalog
is the "root element" of the XML. An XML document can have only one root element).
However, when you do <xsl:apply-templates />
, then this is equivalent to <xsl:apply-templates select="node()" />
which will select the catalog
element. This is where the built-in templates kick in. You don't have a template matching catalog
in your XSLT, and so the built-in one is used.
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
(Here *
matches any element). Thus, this built-in template will select the child nodes of catalog
, and so match the other templates in your XSLT.
Note that, in your second example, you can change the template match to this...
<xsl:template match="/*">
This will match the catalog
element, and so then <xsl:apply-templates select="cd" />
will work.