XML
  Home arrow XML arrow Page 5 - XSL Basics (part 1)
Dev Shed Forums 
Administration  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Download TestComplete 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
IBM Developerworks
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
XML

XSL Basics (part 1)
By: icarus, (c) Melonfire
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 9
    2001-08-15

    Table of Contents:
  • XSL Basics (part 1)
  • A Quick History Lesson
  • Up A Tree
  • Test Drive
  • An Evening At The Moulin Rouge
  • Little Black Book

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
     
    ADVERTISEMENT

    Dell PowerEdge Servers

    XSL Basics (part 1) - An Evening At The Moulin Rouge
    (Page 5 of 6 )

    The preceding example used a single template rule to generate the entire document. While this technique is adequate for simple documents, it becomes difficult to maintain such a stylesheet for a long and complex source tree. Hence XSLT also supports multiple template rules within the same stylesheet, with instructions which tell the processor to recursively traverse the tree for child elements wherever necessary.

    I'll illustrate this with a somewhat more complex XML document:


    <?xml version="1.0"?> <review id="57" category="2"> <title>Moulin Rouge</title> <cast> <person>Nicole Kidman</person> <person>Ewan McGregor</person> <person>John Leguizamo</person> <person>Jim Broadbent</person> <person>Richard Roxburgh</person> </cast> <director>Baz Luhrmann</director> <duration>120</duration> <genre>Romance/Comedy</genre> <year>2001</year> <body> A stylishly spectacular extravaganza, <title>Moulin Rouge</title> is hard to categorize; it is, at different times, a love story, a costume drama, a musical, and a comedy. Director <person>Baz Luhrmann</person> (well-known for the very hip <title>William Shakespeare's Romeo + Juliet</title>) has taken some simple themes - love, jealousy and obsession - and done something completely new and different with them by setting them to music. </body> <rating>5</rating> <teaser>Baz Luhrmann's over-the-top vision of Paris at the turn of the century is witty, sexy...and completely unforgettable</teaser> </review>


    Now, I'd like to present this raw data as the following HTML page:



    Let's look at the stylesheet:


    <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/review"> <html> <head> <basefont face="Arial" size="2"/> </head> <body> <xsl:apply-templates select="title"/> (<xsl:apply-templates select="year"/>) <br /> <xsl:apply-templates select="teaser"/> <p /> <xsl:apply-templates select="cast"/> <br /> <xsl:apply-templates select="director"/> <br /> <xsl:apply-templates select="duration"/> <br /> <xsl:apply-templates select="rating"/> <p> <xsl:apply-templates select="body"/> </p> </body> </html> </xsl:template> <xsl:template match="title"> <b><xsl:value-of select="." /></b> </xsl:template> <xsl:template match="teaser"> <xsl:value-of select="." /> </xsl:template> <xsl:template match="director"> <b>Director: </b> <xsl:value-of select="." /> </xsl:template> <xsl:template match="duration"> <b>Duration: </b> <xsl:value-of select="." /> minutes </xsl:template> <xsl:template match="rating"> <b>Our rating: </b> <xsl:value-of select="." /> </xsl:template> <xsl:template match="cast"> <b>Cast: </b> <xsl:apply-templates/> </xsl:template> <xsl:template match="person[position() != last()]"> <xsl:value-of select="." />, </xsl:template> <xsl:template match="person[position() = (last()-1)]"> <xsl:value-of select="." /> </xsl:template> <xsl:template match="person[position() = last()]"> and <xsl:value-of select="." /> </xsl:template> <xsl:template match="body"> <xsl:apply-templates/> </xsl:template> <xsl:template match="body//title"> <i><xsl:value-of select="." /></i> </xsl:template> <xsl:template match="body//person"> <b><xsl:value-of select="." /></b> </xsl:template> </xsl:stylesheet>


    And the output after running the transformation:


    <html> <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <basefont face="Arial" size="2"> </head> <body> <b>Moulin Rouge</b> (2001) <br>Baz Luhrmann's over-the-top vision of Paris at the turn of the century is witty, sexy...and completely unforgettable<p></p> <b>Cast: </b> Nicole Kidman, Ewan McGregor, John Leguizamo, Jim Broadbent and Richard Roxburgh <br><b>Director: </b>Baz Luhrmann <br><b>Duration: </b>120 minutes <br><b>Our rating: </b>5 <p> A stylishly spectacular extravaganza, <i>Moulin Rouge</i> is hard to categorize; it is, at different times, a love story, a costume drama, a musical, and a comedy. Director <b>Baz Luhrmann</b> (well-known for the very hip <i>William Shakespeare's Romeo + Juliet</i>) has taken some simple themes - love, jealousy and obsession - and done something completely new and different with them by setting them to music. </p> </body> </html>


    Let's dissect this a little. Everything you've just seen stems from the first stylesheet rule, which sets up the order in which I want the various bits of information to appear.


    <xsl:template match="/review"> <html> <head> <basefont face="Arial" size="2"/> </head> <body> <xsl:apply-templates select="title"/> (<xsl:value-of select="year"/>) <br /> <xsl:apply-templates select="teaser"/> <p /> <xsl:apply-templates select="cast"/> <br /> <xsl:apply-templates select="director"/> <br /> <xsl:apply-templates select="duration"/> <br /> <xsl:apply-templates select="rating"/> <p> <xsl:apply-templates select="body"/> </p> </body> </html> </xsl:template>


    This template rule looks for the element "review" - the outermost element - in the source tree - and replaces it with the standard HTML headers in the corresponding result tree. Within the body of the result document, it inserts placeholders for the different pieces of information; each of these placeholders is actually a reference to another template rule.

    The


    <xsl:apply-templates />


    instruction tells the XSLT processor to process all the children of the current node. In case this is too all-inclusive for you, you can refine the list of children to process with an additional "select" attribute, as I've done in the example above.

    While processing the child nodes, the XSLT processor will look for matching templates and apply them wherever possible. In the example above, when the processor receives the instruction


    <xsl:apply-templates select="teaser"/>


    it attempts to find and process template rules matching the element "teaser".


    <xsl:template match="teaser"> <xsl:value-of select="." /> </xsl:template>
    Similarly, I have instructions for the other descriptive information,

    <xsl:apply-templates select="title"/> (<xsl:value-of select="year"/>) <xsl:apply-templates select="director"/> <xsl:apply-templates select="duration"/> <xsl:apply-templates select="rating"/>
    and appropriate templates for each:

    <xsl:template match="title"> <b><xsl:value-of select="." /></b> </xsl:template> <xsl:template match="director"> <b>Director: </b> <xsl:value-of select="." /> </xsl:template> <xsl:template match="duration"> <b>Duration: </b> <xsl:value-of select="." /> minutes </xsl:template> <xsl:template match="rating"> <b>Our rating: </b> <xsl:value-of select="." /> </xsl:template>
    Look what happens when the XSLT processor finds a "body" element:

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


    In this case, the template rule simply tells the processor to act on its children as per other templates which may exist within the stylesheet (strictly speaking, this rule is not really necessary)...and here they are:


    <xsl:template match="body//title"> <i><xsl:value-of select="." /></i> </xsl:template> <xsl:template match="body//person"> <b><xsl:value-of select="." /></b> </xsl:template>


    Now, if you take a look at the XML document, you'll notice that the "title" element occurs in two places - once as the title of the review, and multiple times within the body (to identify movie references). Obviously, I'd like to treat these two occurrences differently - the former should be highlighted as the review title, while the latter should be italicized within the body.

    I'll have XSLT base its decision on the context in which it finds the "title" element - consider these two rules, which do exactly what I need:


    <xsl:template match="title"> <b><xsl:value-of select="." /></b> </xsl:template> <xsl:template match="body//title"> <i><xsl:value-of select="." /></i> </xsl:template>


    Remember what I told you about conflict resolution? Here's an example - the XSLT processor will never apply the first rule to "title" elements within the body, because there already exists a more specific rule to override it.

    In case you're wondering about these,


    <xsl:template match="person[position() != last()]"> <xsl:value-of select="." />, </xsl:template> <xsl:template match="person[position() = (last()-1)]"> <xsl:value-of select="." /> </xsl:template> <xsl:template match="person[position() = last()]"> and <xsl:value-of select="." /> </xsl:template>


    they're simply there to create a grammatically correct string of cast members, and make sure that the commas are all in the right places. The position() and last() functions are XPath functions, and come in very handy if you need to identify the position of any node in a collection.

    By using multiple template rules to control the markup of different elements in the result tree, XSLT makes it possible to break up a complex stylesheet into smaller chunks and thereby easily handle long and convoluted XML data. Breaking up a stylesheet in this manner also makes it simpler to add (or remove) individual template rules for specific elements or sets of elements. The template rules individually create fragments of the result tree; these fragments are then combined into a composite result tree.

    More XML Articles
    More By icarus, (c) Melonfire


     

       

    XML ARTICLES

    - How to Set Up Podcasting and Vodcasting
    - Creating an RSS Reader Application
    - Building an RSS File
    - An Introduction to XUL Part 6
    - An Introduction to XUL Part 5
    - An Introduction to XUL Part 4
    - An Introduction to XUL Part 3
    - An Introduction to XUL Part 2
    - An Introduction to XUL Part 1
    - XML Matters: Practical XML Data Design and M...
    - Practical XML Data Design and Manipulation f...
    - SimpleXML
    - XForms Basics, Part 3
    - XForms Basics, Part 2
    - XForms Basics

     
    Accelerating Trading Partner Performance
     
    Competing on Analytics
     
    Cost Effective Scaling with Virtualization and Coyote Point Systems
     
    Five Checkpoints to Implementing IP Telephony
     
    Hosted Email Security: Staying Ahead of New Threats
     




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway