Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no select in the first apply-templates

Tags:

xml

xslt

I am trying to understand apply-templates but I do not understand why I don't write any select="nodename" in the apply-templates here: (I think of the first apply-templates beneath the My CD collection)

Snippet from the input document:

<?xml version="1.0" encoding="ISO-8859-1"?>
<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>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<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>

Taken from the w3schools tutorial. How does it understand which of the templates it should choose?

like image 342
LuckyLuke Avatar asked Jun 12 '11 20:06

LuckyLuke


People also ask

How does apply-templates work?

You can control processing order by specifying a select attribute on apply-templates . The first apply-templates calls the cd template each time an element named "cd" is encountered. The cd template, in turn calls the title and artist templates to process the children elements of <cd> .

What does xsl apply-templates select mean?

The <xsl:apply-templates> element applies a template to the current element or to the current element's child nodes. If we add a "select" attribute to the <xsl:apply-templates> element, it will process only the child elements that matches the value of the attribute.


1 Answers

As by the specs:

In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes.

apply-templates without XPath selection, applies the templates following the hierarchy of the XML tree view built by the processor during compilation, unless you explicitly drives the templates (as you did for title and artist).

You might also want to think of how built-in template rules work. These rules run behind the scenes and allows recursive process go on in absence of a successful pattern match.

So if you omit the template match for the root / your templates will get executed anyway, thanks to the built-in rules.

I think the processing order should be like this:

  • The template matches the root, and xsl:apply-templates tells the processor to apply the templates to the catalog element (in the place where it is invoked).
  • No matching templates are found for catalog, so that the built-in rule allows continue processing toward the other descendant elements (catalog) until a new template with succesfull pattern match is found (cd)

The built-in rule runs behind the scenes and you must think always your transform as composed by your templates, plus a few additional hidden (but working) templates:

<xsl:template match="*|/">
  <xsl:apply-templates />
</xsl:template>

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="processing-instruction()|comment()"/>

In your specific case the former template among the three above was the one resonsible for applying templates to the cd elements.

These built-in templates gets overridden each time you write an explicit template.


Examples

You can obtain the same by replacing:

<xsl:template match="cd">
    <p>
        <xsl:apply-templates select="title"/>
        <xsl:apply-templates select="artist"/>
    </p>
</xsl:template>

with:

<xsl:template match="country|company|price|year"/>

<xsl:template match="cd">
    <p>
        <xsl:apply-templates />
    </p>
</xsl:template>

About the root, in your case, you could also obtain the same by replacing:

<xsl:template match="/">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

with

<xsl:template match="/catalog">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

or still:

<xsl:template match="/">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates select="catalog"/>
        </body>
    </html>
</xsl:template>

or still:

<xsl:template match="catalog">
    <html>
        <body>
            <h2>My CD Collection</h2>
            <xsl:apply-templates />
        </body>
    </html>
</xsl:template>
like image 66
Emiliano Poggi Avatar answered Nov 12 '22 00:11

Emiliano Poggi