views:

195

answers:

3

Hello everyone,

I am confused about how this XSLT apply-template statement works for cd/title/artist elements in the w3school sample,

http://www.w3schools.com/xsl/xsl_apply_templates.asp

Here is the code snippet I am confused, I am confused when xslt processor finds <xsl:apply-templates/> in below sample, it will match all child nodes of "current node", i.e. the document root's child node, and the child node should be catalog node. But in the XSLT file, there is no template matched for catalog, and only matched for cd/title/artist.

Could anyone let me know after the below template matches for catalog node in <xsl:apply-templates/>, how catalog's child node is processed please?

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

thanks in advance, George

+1  A: 

If no template matches <xsl:apply-templates/>, then will invoke the default action for all child elements, which is equivalent to:

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

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

In other words, text nodes are copied, elements of the source document are removed. In the w3c-schools example, this causes the <catalog> element to be removed. The example contains templates for the child-elements for the <catalog> element, which then are processed.

nd
But in this case, the template with match="cd" will match.
Robert Christie
Isn't "cd matches, even if it's within the catalog element that does not have an explicit template" conceptually similar to "catalog does not have an explicit template, but it matches with a default template that simply calls apply-templates"?
nd
"If no template matches <xsl:apply-templates/>" -- confused. In my sample, catalog node is matched for <xsl:apply-templates/> in the code snippet I posted. Why do you say there is no matched elmement?
George2
2. I think in your sample, match = "*" template will match catalog, and then <xsl:apply-templates/> will select all child (e.g. cd) of catalog, and then cd will be matched to template <xsl:template match="cd">? Is that correct understanding?
George2
@nd Correction to my original comment - "cd" is not matched in the context of the current node - it's only matched when the catalog node comes into context as you define in your answer.
Robert Christie
Thanks for your help, cb160!
George2
+1  A: 

It doesn't just look at the next level of the tree, it looks at the entire hierarchy. The match attribute of "cd" (as opposed to "/cd") matches anywhere in the hierarchy, and so matches the ones under catalog elements.

David M
In this case, catalog is the root node - that's why cd matches. Also, are you sure that the enitre hierarchy is matched - that would appear to make it difficult to restrict searches to the current level only.
Robert Christie
"catalog is the root node" -- I do not agree. Document root is a virtual node which matches /. And in my sample catalog is the child of /, In my sample, catalog node is matched for <xsl:apply-templates/> in the code snippet I posted. I am confused about after catalog is matched, how cd/title/artist elements are matched/processed? Any comments?
George2
Inside of the template match for the root node(which is for the virtual node above the document node, `catalog`) the `apply-templates` match the default template for the `catalog` element, which calls `<apply-templates/>` and then matches the explicit templates for `cd`, `title`, and `artist`. To see that, add a template for "*" and write out the name of the matched element before the `<apply-templates/>` call.
Mads Hansen
Thansk Mads, question answered!
George2
+1  A: 

Looking at the example, the XSL continues with the following templates

<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>

The apply-template in the first template will match against the template with match="cd" as the catalog has cd elements within it. This template then matches the title and artist templates (in that order) as these nodes exist at the cd level.

Matches occur at the current context level - so as the context moves from /catalog to /catalog/cd to /catalog/cd/title and /catalog/cd/title, the relevant templates match and execute.

Robert Christie
"the XSL continues with the following templates" -- why continues to match the following templates? I think only if there are matched element, template will be applied. In my sample quoted, catalog node is matched for <xsl:apply-templates/> in the code snippet I posted. Then after catalog is matched, how did the template cd and title (as you quoted) are processed and matched?
George2
"Matches occur at the current context level - so as the context moves from /catalog to /catalog/cd to /catalog/cd/title and /catalog/cd/title, the relevant templates match and execute." -- is there an XSLT rule for tihs? Could you provide some documents to prove? :-)
George2
The XSLT Spec says "In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node". See http://www.w3.org/TR/xslt#section-Applying-Template-Rules
Robert Christie
Thanks for your help, cb160!
George2