Reputation: 9076
I am new to xslt and i am getting quite a hard time getting used to its xsl:apply-templates element.Here i have a simple xml file and i wnat to apply XSL style on its elements.I want to select every entry element from my XML file and show the title child of it on the screen.I am extracting the section from my XSL file where lies my confusion.
<xsl:template match='/'>
<html>
<head>
<title>my xsl file</title>
</head>
<body>
<h2>my book collection</h2>
<xsl:apply-templates select='entry'/>
</body>
</html>
</xsl:template>
In the above snippet in xsl:apply-templates tag if i use select
attribute,no content is shown on the screen.But if i remove it everything is fine.My question is why is that ? Am i not supposed to select and match the entry tag
.Like the following
<xsl:template match='entry'>
<p>
<xsl:apply-templates select='title'/>
</p>
</xsl:template>
here i have to "select" the "title" tag
form every entry
then have to make a template match for "title" tag.Like the following.Previous snippent selects the title tag and the following snippet matches it and create a h2 tag with its content.Then why we can't do the same thing for entry tag which is the parent of title tag?
<xsl:template match='title'>
<h2 style='color:red;'><xsl:value-of select="."/></h2>
</xsl:template>
FULL code: XML file:
<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type='text/xsl' href='haha.xslt'?>
<book>
<entry>
<title>amar boi</title>
<page>100</page>
</entry>
<entry>
<title>adhunik biggan</title>
<page>200</page>
</entry>
<entry>
<title>machine design</title>
<page>1000</page>
</entry>
</book>
XSL file:
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' >
<xsl:template match='/'>
<html>
<head>
<title>my xsl file</title>
</head>
<body>
<h2>my book collection</h2>
<xsl:apply-templates select='entry'/>
</body>
</html>
</xsl:template>
<xsl:template match='entry'>
<p>
<xsl:apply-templates select='title'/>
</p>
</xsl:template>
<xsl:template match='title'>
<h2 style='color:red;'><xsl:value-of select="."/></h2>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Views: 1008
Reputation: 66781
The root node /
is not the same as the document element /*
(in your case /book
).
In your template matching the root node (xsl:template match="/"
), you are using xsl:apply-templates select="entry"/>
, which is equivalent to /entry
and happens to select nothing.
If you want to apply-templates to the entry
elements, then you could change the first template to match the document element(as @michael.hor257k recommends), or you could adjust the XPath for the apply-templates in the root node template to be: xsl:apply-templates select="book/entry"
, or even */entry"
Complete example:
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0' >
<xsl:template match='/'>
<html>
<head>
<title>my xsl file</title>
</head>
<body>
<h2>my book collection</h2>
<xsl:apply-templates select='book/entry'/>
</body>
</html>
</xsl:template>
<xsl:template match='entry'>
<p>
<xsl:apply-templates select='title'/>
</p>
</xsl:template>
<xsl:template match="title">
<h2 style="color:red;">
<xsl:value-of select="."/>
</h2>
</xsl:template>
</xsl:stylesheet>
Upvotes: 3
Reputation: 117140
In the above snippet in xsl:apply-templates tag if i use select attribute,no content is shown on the screen.But if i remove it everything is fine.My question is why is that ?
The reason for this is that you are in the context of the /
root node (that's what your template matches), and your <xsl:apply-templates/>
is selecting "entry" - which is an abbreviation of "child::entry". However, entry
is not a child of /
, so your expression selects nothing.
If you remove the selection, then templates are applied to nodes that are children of the current node (book
in your example). The built-in template rule then applies templates to the children of book
and that is how your template matching entry
is eventually applied.
You could avoid this problem simply by changing your first template's start-tag to:
<xsl:template match='/book'>
Upvotes: 3