AL-zami
AL-zami

Reputation: 9076

proper use of xpath for "select=" attribute in xsl:apply-templates tag

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

Answers (2)

Mads Hansen
Mads Hansen

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

michael.hor257k
michael.hor257k

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

Related Questions