XML

 


COIN78 - XML Lesson 9: XSL eXtensible Stylesheet Language


Matching Elements with XSL

  1. Basic XML rendering using XSL. XSL is a 'helper application' of XML, that applies a set of literal and conditional templates to your XML file. You link to your XSL file using this processing statement<?xml-stylesheet type="text/xsl" href="para.xsl"?> as shown in the file para_xsl.xml:

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="para.xsl"?>
    <para>This is a
        <emphasis>test</emphasis>.
    </para>    

    This is how we apply the stylesheet para.xsl to the root file para.xml . Notice that in the XSL stylesheet para.xsl, we use a special XSL output statement <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/> - you must use this when rendering XML using XSL using MSXML version 4.0 XML parser. In the stylesheet, we match the template 'para' to the XML element 'para', which in turn uses the HTML element <em> for italicizing. There are a number of different mechanisms to do this, as you will see in the example files, but this is the easiest to follow.

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="para">
          <p>
              <xsl:apply-templates />
          </p>
      </xsl:template>
      
      <xsl:template match="emphasis">
          <em>
              <xsl:apply-templates />
          </em>
      </xsl:template>
    </xsl:stylesheet>

    Now we'll take that basic approach to rendering the now infamous CD catalog series developed by Jan Egil Refsnes. The root file CD catalog, is shown in cdcatalog.xml and rendered with XSL is cdcatalog_xsl.xml, using an XSL stylesheet cdcatalog.xsl. Notice how we match a root template to the document root itself - <xsl:template match="/">. This applies the entire template (cdcatalog.xsl) to our XML document (cdcatalog_xsl.xml).

    This example uses html tables which will be discussed later in the XML to HTML section.

    <?xml version="1.0"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <body>
            <h2>My CD Collection</h2>
            <table border="1">
              <tr style="background-color:#9acd32;">
                <th align="left">Title</th>
                <th align="left">Artist</th>
              </tr>
              <xsl:for-each select="catalog/cd">
                <tr>
                  <td><xsl:value-of select="title"/></td>
                  <td><xsl:value-of select="artist"/></td>
                </tr>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template
    </xsl:stylesheet>

  2. We display all the records using an xsl:for-each statement <xsl:for-each select="catalog/cd"> and then display the song and artist by pairing an xsl:value-of statement to each of the title and artist elements, diplaying them in a <td> table data cell: <xsl:value-of select="title"/> and <xsl:value-of select="artist"/>.

    Let's take a look at this in a series of steps, first by dispalying one record, rendering cdcatalog_ex1_xsl.xml with cdcatalog_ex1.xsl. The match attribute is used to associate a template with an XML element. The match attribute can also be used to define a template for the entire XML document. The value of the match attribute is an XPath expression (i.e. match="/" defines the whole document). The combination of the series of steps are shown in the xsl shown at the end of this discussion. Click here to see it.

  3. Since an XSL style sheet is an XML document itself, it always begins with the XML declaration: <?xml version="1.0" encoding="UTF-8"?>. The next element, <xsl:stylesheet>, defines that this document is an XSLT style sheet document (along with the version number and XSLT namespace attributes).

    The <xsl:template> element defines a template. The match="/" attribute associates the template with the root of the XML source document.

    The content inside the <xsl:template> element defines some HTML to write to the output.

    The last two lines define the end of the template and the end of the style sheet.

  4. The <xsl:value-of> Element - The second catalog example dispalying the value of an element as shown in rendering cdcatalog_ex2_xsl.xml with cdcatalog_ex2.xsl. The <xsl:value-of> element can be used to extract the value of an XML element and add it to the output stream of the transformation. Note: The value of the select attribute is an XPath expression. An XPath expression works like navigating a file system; where a forward slash (/) selects subdirectories.

  5. In the next chapter you will learn how to use the <xsl:for-each> element to loop through the XML elements, and display all of the records. The XSL <xsl:for-each> element can be used to select every XML element of a specified node-set, the the third catalog example dispalying all records, is shown rendering cdcatalog_ex3_xsl.xml with cdcatalog_ex3.xsl.

    <?xml version="1.0"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <body>
            <h2>My CD Collection</h2>
            <table border="1">
              <tr style="background-color:#9acd32;">
                <th>Title</th>
                <th>Artist</th>
              </tr>
              <xsl:for-each select="catalog/cd">
                <tr>
                  <td>
                    <xsl:value-of select="title"/>
                  </td>
                  <td>
                    <xsl:value-of select="artist"/>
                  </td>
                </tr>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>

Pattern Matching

  1. Filtering the Output - you can also filter the output from the XML file by adding a criterion to the select attribute in the <xsl:for-each> element.

    <xsl:for-each select="catalog/cd[artist='Bob Dylan']">

    Legal filter operators are:

    • =  (equal)
    • != (not equal)
    • &lt; less than
    • &gt; greater than

    Take a look at the adjusted XSL style sheet cdcatalog_filter.xsl as it applies to cdcatalog_xsl_filter.xml

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <html>
                <body>
                    <table border="1">
                        <tr style="background-color:#9acd32;">
                          <th>Title</th>
                          <th>Artist</th>
                        </tr>
                        <xsl:for-each select="catalog/cd[artist='Bob Dylan']">
                            <tr>
                                <td><xsl:value-of select="title"/></td>
                                <td><xsl:value-of select="artist"/></td>
                            </tr>
                        </xsl:for-each>
                    </table>
                </body>
            </html>
        </xsl:template>
    </xsl:stylesheet>

  2. The <xsl:if> Element to put a conditional if test against the content of the XML file, add an <xsl:if> element to the XSL document. The syntax is:

    <xsl:if test="expression">  ...some output if expression is true... </xsl:if>

    The conditional test above is shown in cdcatalog_if_xsl.xml and the XSL file in cdcatalog_if.xsl we test for if the price of the album is greater than $10. Try changing the if statement and viewing the different output files, for example if price is = to $10, or if price is less than $10. Make sure to use the > for > and < for <, as these are built in entities.

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <html>
                <body>
                    <h2>My CD Collection</h2>
                    <table border="1">
                        <tr style="background-color:#9acd32;">
                            <th>Title</th>
                            <th>Artist</th>
                        </tr>
                        <xsl:for-each select="catalog/cd">
                            <xsl:if test="price&gt;10">
                                <tr>
                                    <td><xsl:value-of select="title"/></td>
                                    <td><xsl:value-of select="artist"/></td>
                                </tr>
                            </xsl:if>
                        </xsl:for-each>
                    </table>
                </body>
            </html>
        </xsl:template>
    </xsl:stylesheet>

  3. The <xsl:choose> Element - this allows the template to test for a condition, and choose the output based on whether that condition is met or not. To insert a multiple conditional test against the XML file, add the <xsl:choose>, <xsl:when>, and <xsl:otherwise> elements to the XSL file:

        <xsl:choose><
            xsl:when test="expression">      ... some output ...  </xsl:when>    
            <xsl:otherwise>      ... some output ....    </xsl:otherwise>  
        </xsl:choose>

    The condition above can be used to print a statement if the price is equal to some value, a differnet output if it is greater, and a differnet output still if it is less.

    These are shown in cdcatalog_choose_xsl.xml and the stylesheet cdcatalog_choose.xsl for a single test, and cdcatalog_choose2_xsl.xml using the XSL stylesheet cdcatalog_choose2.xsl

    Below is the xsl showing several choices. If the price is greater than 10 the first choice is selected. If the price is greater than 9 then the second choice is selected. All other prices fall into the otherwise option.

    <?xml version="1.0"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <body>
            <h2>My CD Collection</h2>
            <table border="1">
              <tr style="background-color:#9acd32;">
                <th>Title</th>
                <th>Artist</th>
              </tr>
              <xsl:for-each select="catalog/cd">
                <tr>
                  <td>
                    <xsl:value-of select="title"/>
                  </td>
                  <xsl:choose>
                    <xsl:when test="price &gt; 10">
                      <td style="background-color:#ff00ff;">
                        <xsl:value-of select="artist"/>
                      </td>
                    </xsl:when>
                    <xsl:when test="price &gt; 9">
                      <td style="background-color:#cccccc;">
                        <xsl:value-of select="artist"/>
                      </td>
                    </xsl:when>
                    <xsl:otherwise>
                      <td>
                        <xsl:value-of select="artist"/>
                      </td>
                    </xsl:otherwise>
                  </xsl:choose>
                </tr>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>

  4. The <xsl:sort> element is used to sort the output. In our example we will be sorting on the artists. Notice that the sort statement is not a nested element. This is shown in cdcatalog_sort_xsl.xml and cdcatalog_sort.xsl.

    <?xml version="1.0"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <body>
            <h2>My CD Collection</h2>
            <table border="1">
              <tr style="background-color:#9acd32;">
                <th>Title</th>
                <th>Artist</th>
              </tr>
              <xsl:for-each select="catalog/cd">
                <xsl:sort select="artist"/>
                <tr>
                  <td>
                    <xsl:value-of select="title"/>
                  </td>
                  <td>
                    <xsl:value-of select="artist"/>
                  </td>
                </tr>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>

    Next, we will be sorting based on price in ascending order. The data-type must be set to number to let the parser know that the items being sorted are numbers otherwise it treats the values as text. These are shown in cdcatalog_sort_price_xsl.xml and cdcatalog_sort_price.xsl.

    <?xml version="1.0"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <body>
            <h2>My CD Collection</h2>
            <table border="1">
              <tr style="background-color:#9acd32;">
                <th>Title</th>
                <th>Artist</th>
              </tr>
              <xsl:for-each select="catalog/cd">
                <xsl:sort select="price" data-type="number" order="ascending"/>
                <tr>
                  <td>
                    <xsl:value-of select="title"/>
                  </td>
                  <td>
                    <xsl:value-of select="artist"/>
                  </td>
                  <td>
                    <xsl:value-of select="price"/>
                  </td>
                </tr>
              </xsl:for-each>
            </table>
          </body>
        </html>
      </xsl:template>
    </xsl:stylesheet>

  5. Using the <xsl:apply-templates> element for choosing and formatting nodes.

    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 element that matches the value of the attribute. We can use the select attribute to specify the order in which the child nodes are processed. Look at the following XSL style sheet (show code)

    We apply the template to choose the title and artist nodes, and apply separate styles to each, and display in a table format. These are shown in cdcatalog_apply_xsl.xml using the stylesheet cdcatalog_apply.xsl

    <?xml version="1.0"?>
    <!-- Edited with XML Spy v2007 (http://www.altova.com) -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <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>

  6. Using JavaScript for server side scripting. You can use an interesting block of code shown here to transform the cdcatalog.xml file using the cdcatalog.xsl file. It can also be tested using a remote server from this link.

XPath Functions in XSLT

XPath looks at an XML document as a tree. Each element is a branch that may have branches of its own. In XSLT, XPath is used to match nodes from the source document for output templates via the match attribute of the xsl:template tag.

This example XML Document will be used for this section.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="people.xsl"?>
<!DOCTYPE people [
 <!ATTLIST homepage xlink:type CDATA #FIXED "simple"
                  xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
 <!ATTLIST person id ID #IMPLIED>
]>
<people>
 
  <person born="1912" died="1954" id="p342">
    <name>
      <first_name>Alan</first_name>
      <last_name>Turing</last_name>
    </name>
    <!-- Did the word computer scientist exist in Turing's day? -->
    <profession>computer scientist</profession>
    <profession>mathematician</profession>
    <profession>cryptographer</profession>
    <homepage xlink:href="http://www.turing.org.uk/"/>
  </person>
 
  <person born="1918" died="1988" id="p4567">
    <name>
      <first_name>Richard</first_name>
      <middle_initial>&#x4D;</middle_initial>
      <last_name>Feynman</last_name>
    </name>
    <profession>physicist</profession>
    <hobby>Playing the bongoes</hobby>
  </person>
 
</people>

This XSLT template uses the position( ) function to calculate the number of the person being processed, relative to other nodes in the context node list:

<xsl:template match="person">
  Person <xsl:value-of select="position(  )"/>,
  <xsl:value-of select="name"/>
</xsl:template>

In this example the position( ) function tells you which person element is currently being processed, and the count( ) function tells you how many total person elements exist in the document.

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
  <xsl:template match="people">
    <xsl:apply-templates select="person"/>
  </xsl:template>
 
  <xsl:template match="person">
    Person <xsl:value-of select="position(  )"/> 
    of <xsl:value-of select="count(//person)"/>:
    <xsl:value-of select="name"/>
  </xsl:template>
 
</xsl:stylesheet>

XPath includes functions for basic string operations, such as finding a string's length or changing letters from uppercase to lowercase. It doesn't have the full power of the string libraries in Python or Perl; for example, there's no regular expression support. However, XPath is sufficient for many simple manipulations you need for XSLT or XPointer.

We will look at the string-length(), string(), and normalize_space() functions and apply them to our example.

Function Result
string-length(//name[position( )=1]) Returns a number giving the length of the string value of its argument, or of the context node if no argument is included. In our example it is 29.
string(//name[position( )=1])

Returns a string. In our example it returns:

alan
turing
normalize-space (string(//name[position( )=1]))

Trims and normalizes space. In our example it returns:

alan turing


For a complete list of the functions visit:


XML to HTML

  1. Adding HTML

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="xsl11.xsl"?>
    <students>
       <student class="coin1000">
          <first_name>Dan</first_name>
          <last_name>Cole</last_name>
          <id>600322456</id>
          <homeworks>
             <homework>
                <id>HW1</id>
                <points>10</points>
             </homework>
          </homeworks>
       </student>
    </students>

    One of the uses of XSL is for converting XML documents to HTML in order to allow viewers with non-XML browsers to view the website. Converting XML to HTML follows the pattern matching which we have been doing with an exception of adding HTML tags around the "value-of" tags.

    One important thing that we need to remember is that XSL is an XML document, therefore all of our HTML tag must follow the well-formedness rules of XML document: Each tag needs to be closed or be treated as an XML empty tag (<br />).

    In this example we have wrapped the "html" and "body" around the root node. Since these tags are not visible by themselves we added the text "CLASS" as the header on the page as visible indication.

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:template match="/">
            <html>
                <body>
                    <h3>CLASS</h3>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
    
    </xsl:stylesheet>

  2. Adding h2 In this example we have taken the attribute value of our class and have used the "h2" tag to display our class name.

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <html>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
            
        <xsl:template match="students/student">
            <h2> CLASS: <xsl:value-of select="@class"/></h2>
        </xsl:template>
        
    </xsl:stylesheet>

  3. Displaying with p In this example we have added a few more records and are placing them all together inside a "p" tag.

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="xsl13.xsl"?>
    <students  class="COIN1000">
        <student>
            <first_name>James</first_name>
            <last_name>Smith</last_name>
            <id>12345</id>
            <homeworks>
                <homework>
                    <number>1</number>
                    <score>10</score>
                </homework>
                <homework>
                    <number>2</number>
                    <score>8</score>
                </homework>
                <homework>
                    <number>3</number>
                    <score>9</score>
                </homework>
            </homeworks>
        </student>
        <student>
            <first_name>Bob</first_name>
            <last_name>Clark</last_name>
            <id>34567</id>
    		<homeworks>
                <homework>
                    <number>1</number>
                    <score>6</score>
                </homework>
                <homework>
                    <number>2</number>
                    <score>9</score>
                </homework>
                <homework>
                    <number>3</number>
                    <score>7</score>
                </homework>
                <homework>
                    <number>4</number>
                    <score>5</score>
                </homework>
            </homeworks>
        </student>
        <student>
            <first_name>Tony</first_name>
            <last_name>Cole</last_name>
            <id>73456</id>
            <homeworks>
                <homework>
                    <number>1</number>
                    <score>8</score>
                </homework>
                <homework>
                    <number>2</number>
                    <score>4</score>
                </homework>
                <homework>
                    <number>3</number>
                    <score>10</score>
                </homework>
                <homework>
                    <number>4</number>
                    <score>10</score>
                </homework>
                <homework>
                    <number>5</number>
                    <score>6</score>
                </homework>
                <homework>
                    <number>6</number>
                    <score>8</score>
                </homework>
            </homeworks>
        </student>
        <student>
            <first_name>Mike</first_name>
            <last_name>Shen</last_name>
            <id>43433</id>
            <homeworks>
                <homework>
                    <number>1</number>
                    <score>3</score>
                </homework>
                <homework>
                    <number>2</number>
                    <score>5</score>
                </homework>
                <homework>
                    <number>3</number>
                    <score>9</score>
                </homework>
            </homeworks>
        </student>
        <student>
            <first_name>Jennifer</first_name>
            <last_name>Davidson</last_name>
            <id>56353</id>
            <homeworks>
                <homework>
                    <number>1</number>
                    <score>8</score>
                </homework>
                <homework>
                    <number>2</number>
                    <score>4</score>
                </homework>
                <homework>
                    <number>3</number>
                    <score>5</score>
                </homework>
            </homeworks>
        </student>
        <student>
            <first_name>Mathew</first_name>
            <last_name>Bone</last_name>
            <id>76544</id>
            <homeworks>
                <homework>
                    <number>1</number>
                    <score>7</score>
                </homework>
                <homework>
                    <number>2</number>
                    <score>4</score>
                </homework>
                <homework>
                    <number>3</number>
                    <score>6</score>
                </homework>
            </homeworks>
        </student>
    </students>

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <html>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
     
        <xsl:template match="students">
            <h2> CLASS: <xsl:value-of select="@class"/></h2>
            <p><xsl:value-of select="."/></p>
        </xsl:template>
        
    </xsl:stylesheet>

  4. FOR EACH This example is identical as above except we are using the "xsl:for-each" looping element. Our XSL instructions will loop bases on the number of students, "xsl:for-each select="/students/student". As the result with each iteration the students record are wrapped inside a pair of "P" tags.

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <html>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
        
        <xsl:template match="students">
            <h2> CLASS: <xsl:value-of select="@class"/></h2>
            
            <xsl:for-each select="/students/student">
                <p><xsl:value-of select="."/></p>
            </xsl:for-each>
            
        </xsl:template>
        
    </xsl:stylesheet>

  5. TABLES Now, we have taken our records and instead of using "p" tags, every student is in a separate row "tr".

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <html>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
        <xsl:template match="students">
            <h2> CLASS: <xsl:value-of select="@class"/></h2>
            <table>
                <xsl:for-each select="/students/student">
                <tr>
                    <td><xsl:value-of select="."/></td>
                </tr>
                </xsl:for-each>
            </table>
        </xsl:template>
    </xsl:stylesheet>

  6. TABLES Now, we have added more styles to the table, centering, color, borders. We are, also, displaying the first name, last name, and id in the cells for each student. Each student is in a separate row.

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <html>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>
    
        <xsl:template match="students">
            <h1 style="text-align:center;"> CLASS: <xsl:value-of select="@class"/></h1>
            <table align="center" cellpadding="5px" border="1" 
                   style="background-color:#DFF0FF;">
                <xsl:for-each select="/students/student">
                    <tr>
                        <td><xsl:value-of select="first_name"/></td>
                        <td><xsl:value-of select="last_name"/></td>
                        <td><xsl:value-of select="id"/></td>
                    </tr>
                </xsl:for-each>
            </table>
        </xsl:template>
    
    </xsl:stylesheet>

  7. TABLES Now, we are changing the example from above to use a template to fill in the cells.

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:template match="/">
            <html>
              <body>
                  <xsl:apply-templates/>
              </body>
            </html>
        </xsl:template>

    <xsl:template match="students"> <h1 style="text-align:center;"> CLASS: <xsl:value-of select="@class"/></h1> <table align="center" cellpadding="5px" border="1" style="background-color:#DFF0FF;"> <xsl:apply-templates select="student"/> </table> </xsl:template> <xsl:template match="student"> <tr> <td><xsl:value-of select="first_name"/></td> <td><xsl:value-of select="last_name"/></td> <td><xsl:value-of select="id"/></td> </tr> </xsl:template> </xsl:stylesheet>

  8. NESTING TABLES We can go one step further and apply the "for-each" looping syntax inside another one (this is what programmers call nested loops) to create a nested table of data. This example requires a bit of think and digesting.

    Click here To view the XSL

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:template match="/">
            <html>
                <body>
                    <xsl:apply-templates/>
                </body>
            </html>
        </xsl:template>

    <xsl:template match="students"> <h2 style="text-align:center;"> CLASS: <xsl:value-of select="@class"/></h2> <table align="center" cellpadding="5px" border="1" style="background-color:#DFF0FF;"> <xsl:for-each select="/students/student"> <tr valign="top"> <td><xsl:value-of select="first_name"/></td> <td><xsl:value-of select="last_name"/></td> <td><xsl:value-of select="id"/></td> <td style="background-color:#FFC;"> <table cellpadding="5px"> <xsl:for-each select="homeworks/homework"> <tr> <td><xsl:value-of select="number"/></td> <td><xsl:value-of select="score"/></td> </tr> </xsl:for-each> </table> </td> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>

  9. IMAGES The image template is constructed in a similar way. We leave it as further exercise for you to decide how to create a template for an image link.....
    <xsl:template match="picture">
    <img>
    <xsl:attribute name="src"><xsl:value-of select="./@filename"/></xsl:attribute>
    <xsl:attribute name="width"><xsl:value-of select="./@x"/></xsl:attribute>
    <xsl:attribute name="height"><xsl:value-of select="./@y"/></xsl:attribute>
    </img>
    </xsl:template>
    Below we see how the image is contructed

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <head>
            <title>Using XSL to display images and links</title>
          </head>
          <body>  
              <div style="width:550px; margin:10px auto; text-align:center;">              
                  <h1>Using XSL to display images and links</h1>
                  <div style="margin:10px;"><xsl:apply-templates select="//picture" /></div>
                  <div style="text-align:left"><xsl:apply-templates select="//website"/></div>
                  <div style="text-align:left"><xsl:apply-templates select="//email"/></div>
              </div>
          </body>
        </html>
      </xsl:template>
      <xsl:template match="picture">
        <img>
          <xsl:attribute name="src"><xsl:value-of select="./@filename"/></xsl:attribute>
          <xsl:attribute name="width"><xsl:value-of select="./@x"/></xsl:attribute>
          <xsl:attribute name="height"><xsl:value-of select="./@y"/></xsl:attribute>
        </img> 
      </xsl:template> <!-- html image: <img src="image name" width="x" height="y" /img> -->
      <xsl:template match="website">
        <a>
          <xsl:attribute name="href"><xsl:value-of select="./@href"/></xsl:attribute>
          <xsl:attribute name="title"><xsl:value-of select="."/></xsl:attribute>
          <xsl:value-of select="."/>
        </a>
      </xsl:template> <!-- html link: <a href="http://link">link name</a> -->
      <xsl:template match="email">
        <a>
          <xsl:attribute name="href">mailto:<xsl:value-of select="@href"/></xsl:attribute>
          <xsl:attribute name="title"><xsl:value-of select="."/></xsl:attribute>
          <xsl:value-of select="."/>
        </a>
      </xsl:template>
    </xsl:stylesheet>

    See the file formatting.xml, formatting_xsl.xml and formatting.xsl You can download the zipped archive formatting.zip

  10. LINKS This example requires a bit of thought and digesting. The key for both links and images is to create a template based on the tag name; in the LINK example, the template is "title/html:a". Then, in the template definition, you need to describe a standard link in terms of the tags and attributes used in the XML file.

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- edited with XML Spy v4.4 U (http://www.xmlspy.com) by Robert Cormia 
         (Foothill College) -->
    <?xml-stylesheet type="text/xsl" href="formatting.xsl"?>
    
    <formatting>
        <picture filename="metaman.jpg" x="137" y="200"/>
        <website href="http://www.amazon.com/exec/obidos/ASIN/038525380X/">
            Metaman: The Merging of Humans and Machines into a Global Superorganism
        </website>
        <email href="user@whatever.com">Send email</email>
    </formatting>

    <a> --- the html open link tag
    <xsl:attribute name="href"> --- the html link href attribute
    <xsl:value-of select="./@href" /> --- value of the the link attribute used in the xml file
    </xsl:attribute> --- closes the link href attribute
    <xsl:value-of /> --- the link value used in the xml file
    </a> --- the close link tag

    Below we see how the web site link is constructed which is highlighted in blue.

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
      <xsl:template match="/">
        <html>
          <head>
            <title>Using XSL to display images and links</title>
          </head>
          <body>        
              <div style="width:550px; margin:10px auto; text-align:center;">              
                  <h1>Using XSL to display images and links</h1>
                  <div style="margin:10px;"><xsl:apply-templates select="//picture" /></div>
                  <div style="text-align:left"><xsl:apply-templates select="//website"/></div>
                  <div style="text-align:left"><xsl:apply-templates select="//email"/></div>
              </div>
          </body>
        </html>
      </xsl:template>
      <xsl:template match="picture">
        <img>
          <xsl:attribute name="src"><xsl:value-of select="./@filename"/></xsl:attribute>
          <xsl:attribute name="width"><xsl:value-of select="./@x"/></xsl:attribute>
          <xsl:attribute name="height"><xsl:value-of select="./@y"/></xsl:attribute>
        </img>
      </xsl:template> <!-- html image: <img src="image name" width="x" height="y" /img> -->
      <xsl:template match="website">
        <a>
          <xsl:attribute name="href"><xsl:value-of select="./@href"/></xsl:attribute>
          <xsl:attribute name="title"><xsl:value-of select="."/></xsl:attribute>
          <xsl:value-of select="."/>
        </a>  
      </xsl:template> <!-- html link: <a href="http://link">link name</a> -->
      <xsl:template match="email">
        <a>
          <xsl:attribute name="href">mailto:<xsl:value-of select="@href"/></xsl:attribute>
          <xsl:attribute name="title"><xsl:value-of select="."/></xsl:attribute>
          <xsl:value-of select="."/>
        </a>
      </xsl:template>
    </xsl:stylesheet>

    See the file formatting.xml, formatting_xsl.xml and formatting.xsl. You can download the zipped archive formatting.zip


Example Files

Now that you have worked through the tutorials, you would like to see some elegant examples. (Right click to download the links). The first is a conservative style which is also very elegant, and adds links to both the email address and to the website links. It is shown in address_book_xsl.xml and address_book.xsl.

Visit zvon.org to see a couple of examples that show the xml, xsl stylesheet, and the output.

References

Links to XML Related Sites

  1. XML.COM
  2. WDVL XML tutorial
  3. Sun Java XML Introduction
  4. IBM'S XML Website
  5. Google Directory on XML

Up Arrow Top