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

Close    To Top
  • Prev Article-XML:
  • Next Article-XML:
  • Now: Tutorial for Web and Software Design > XML > Styles > XML Content
    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
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction