Now: Tutorial for Web and Software Design > XML > Styles > XML Content
> Dirty XSLT Output [Bookmark it]
Dirty XSLT Output
Dirty XSLT Output

Dirty XSLT Output

by John E. Simpson
September 25, 2002

Why am I getting dirty output?

I have observed "dirty output" applying different template rules that look equivalent to me. The source document is:

   <world>

      <country>

         <appellative>

            <name>United States of

America</name>

         </appellative>

         <government>

            <executive_branch>

               <chief_of_state>

                  <name>George W.</name>

                  <surname>Bush</surname>

               </chief_of_state>

            </executive_branch>

         </government>

      </country>

   </world>

I'm looking for this (partial) result:

   ...

   <table border="1">

      <tr>

         <td>George W. Bush</td>

      </tr>

   </table>

    ...

I can get this result using the following transformation (call it Transformation #1):

   <xsl:template match="world">

      <html>

         <head>

            <title>world</title>

         </head>

         <body>

            <table border="1">

               <xsl:apply-templates

select="country"/>

            </table>

         </body>

      </html>

   </xsl:template>



   <xsl:template match="country">

      <tr>

         <td> 

            <xsl:value-of

select="government/executive_branch/chief_of_state"/>

         </td>

      </tr>

   </xsl:template>

I've also tried this transformation (call it Transformation #2; compare the boldfaced portions with their counterparts above):

   <xsl:template match="world">

      <html>

         <head>

            <title>world</title>

         </head>

         <body>

            <table border="1">

               <xsl:apply-templates

select="country"/>

            </table>

         </body>

      </html>

   </xsl:template>



   <xsl:template match="country/government">

      <tr>

         <td> 

            <xsl:value-of

select="executive_branch/chief_of_state"/>

         </td>

      </tr>

   </xsl:template>

What I actually get from the latter, though, is this:

   ...

   <table border="1">United States of America

      <tr>

         <td>George W. Bush</td>

      </tr>

    ...

Why, in this case, does "United States of America" come out? I think the problem is in the xsl:apply-templates element, but I do not understand why. Can you help me?

A: You're on the right track; the problem is indeed related to the xsl:apply-templates element. More exactly, it's attributable to the cumulative effect of that element together with the explicit or implicit template rules elsewhere in the stylesheet.

By "explicit" template rules, I mean the template rules -- xsl:template elements and their descendants -- which you've expressly coded in your stylesheet. In Transformation #1, notice that there's a direct correspondence between the value of the xsl:apply-templates element's select attribute (whose value is "country") and the match attribute of an xsl:template rule.

In your Transformation #2, though, there is no such direct correspondence. While the select attribute still has the value "country," there are no match attributes with this value; the only other template rule matches on "country/government" instead. What you've run afoul of here is not the template rules you've explicitly coded, but the built-in template rules established by the XSLT 1.0 Recommendation. These are the "implicit" template rules.

Built-in template rules are defined for the root node, elements, text, attributes, comments, and processing instructions (PIs). The two built-ins causing the mysterious-seeming discrepancy in Transformation #2 are those for element and text nodes:

   <!-- Element nodes with no explicit

template rule -->

   <xsl:template match="*">

      <xsl:apply-templates />

   </xsl:template>



   <!-- Text nodes with no explicit template rule

-->

   <xsl:template match="text()">

      <xsl:value-of select="." />

   </xsl:template>

The built-in template rule for element nodes says, "Process all template rules -- including built-in ones, if necessary -- for all children of the context element node." Note that the term "children" covers not only child elements, but also child text, comment, and PI nodes. For a given text node, the built-in template rule simply transfers the string-value of the text node straight to the result tree. In both cases, as with the other built-in template rules, the built-ins are automatically processed by the XSLT processor just as if you'd explicitly coded them in your stylesheet -- unless you explicitly override them, or provide some other constraint which keeps them from kicking in.

[1] [2] Next

[Bookmark][Print] [Close][To Top]
  • Prev Article-XML:

  • Next Article-XML:
  • Related Materias
    Printing XML: Why CSS Is B
    Converting XML  to RDF
    Utility Stylesheets, Part 
    Overriding Concerns
    Diagramming the XML Family
    New and Improved String Ha
    Understanding the node-set
    Shortening XSLT Stylesheet
    Automatic Numbering, Part 
    Finding the First, Last, B
    Topics
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Graphic Design Tutorial
     

    Coreldraw Tutorial

      Illustrator Tutorial
      3D Graphics Articles
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial&Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial&Articles
     

    XML Style Tutorial

      AJAX Tutorial
      XML Mobile
    Flash Tutorial&Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial&Articles
     

    Linux Tutorial

      Symbian Tutorial
      MacOS Tutorial