What is XSLT?
As described in what_is_xml, the XML file is only the data part of the whole XML concept. For transforming and formatting the information, XSLT (XSL Transformations) respectively XSL (Extensible Stylesheet Language) is used, whereas XSLT can be seen as a part of XSL (as it is shown in the picture below). Both of the XML sublanguages use the XML Path Language (XPath) for addressing data and therefore they use the same data model. But only the XSLT part has been needed to build XIG and therefore only this part is explained here.

(modified graph from: Henning Behme & Stefan Mintert, "XML in der Praxis", Addison-Wesley, 2000)
Now, as it should be clear that XSLT transformations are XML to XML and tree to tree transformations, it would be interesting to know, how XSLT works. The following graph shows the single steps, XSLT is doing while transforming an XML fragment - to transform the whole document, the procedure has to be repeated, of course.

As shown, there are two possible ways to initiate a transformation step. To change the structure of the source tree fragment and built up the target tree fragment, either a pattern has to match the source structure or a named template has to be called. Both of these approaches are template rules, which are the main component of XSLT stylesheets.
These template rules are so called top-level elements, what means that they are direct children of the stylesheets root element <xsl:stylesheet>. This root element contains the version of the used XSLT definition and its namespace as attributes, wherefore a simple stylesheet may look like the following code:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/"> </xsl:template>
</xsl:stylesheet> |
As it can be seen, the XSLT stylesheet is also an XML document, therefore it normally contains the standard processing instruction. Furthermore, this stylesheet contains one template, which has the pattern "/". That means that this template would match the root element of the source tree and therefore is the starting point of the transformation. In the following, the most important top-level elements are listed and explained (please reference the XSLT recommendation for further information or click on the single elements for details):
| xsl:import | This element allows the import of an XSLT stylesheet, whereas the actual stylesheet has a higher priority than the imported one. |
| xsl:include | This element simply copies the specified stylesheet into the actual one. |
| xsl:output | The output element specifies the target code in terms of e.g. format, used character set and used DTD. |
| xsl:variable | This element offers the possibility of defining variables with a specified value. |
| xsl:key | The key element allows the generation of cross-references, which can seriously accelerate the speed of the transformation. |
| xsl: template | This is the already known template element, which is able to operate with the help of a defined pattern or a specified name. |
In the next code fragment some of these elements are used:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="old_sheet.xsl"/> <xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-system="gxl.dtd"/> <xsl:variable name="info" select="/header/info/text()"/>
<xsl:template match="/"> </xsl:template>
</xsl:stylesheet> |
In this extended example the stylesheet old_sheet.xsl has been imported and the target code is set to xml. Furthermore, the version of the produced xml code is 1.0, the used character set is set to UTF-8 and the target file references the gxl.dtd as its DTD. Also the variable info is available from now on - it contains the text nodes of the axis /header/info.
To built up the target tree, some more basic elements are needed, which are able to create the single elements of the target structure. The next table contains the most important basic elements (please reference the XSLT recommendation for further information or click on the single elements for details):
| xsl:element | This XSLT element creates a simple element (e.g. <element/>). |
| xsl:attribute | This element adds an attribute to the sourrounding element (e.g. <element attribute="content"/>). |
| xsl:attribute-set | This one is similar to the previous, but is able to create a specified amount of attributes (e.g. <element attribute1="content" attribute2="content"/>). |
| xsl:text | The task of this element is the creation of simple text - also whitespaces. The result may be not well formed. |
| xsl:processing-instruction | Processing Instructions can be built be these XSLT elements (e.g. <?program version="1.0"?>). |
| xsl:comment | This elements add comments to the target code (e.g. <!-- this is a comment -->). |
| xsl:copy | The XSLT copy element provides the possibility of copying the current element. |
| xsl:value-of | Selects the content of a specified element or attribute. |
In the next code fragment some of these elements are used:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="old_sheet.xsl"/> <xsl:output method="xml" version="1.0" encoding="UTF-8" doctype-system="gxl.dtd"/> <xsl:variable name="info" select="/header/info/text()"/>
<xsl:template match="/">
<xsl:processing-instruction name="program">version="1.0"</xsl:processing-instruction> <xsl:comment>this is a simple element</xsl:comment><xsl:element name="elem"> <xsl:attribute name="first_elem_attr"> <xsl:text>content</xsl:text> </xsl:attribute> <xsl:attribute name="second_elem_attr"> <xsl:value-of select="($info)"/> </xsl:attribute> </xsl:element>
</xsl:template> </xsl:stylesheet> |
As it can be seen, the example has been extended again; as child elements of the only template, a Processing Instruction element and a comment element have been inserted - these create the specified Processing Instruction (<?program version="1.0"?>) and comment (<!-- this is a simple element -->) in the target code. The element which is created next (<elem></elem>) contains two attributes, first_elem_attr and second_elem_attr. The first one contains the simple text "content" and the second the value of the defined variable info.
Now it is possible to create a simple target tree, but more complex structures respectively completely changed trees can not be produced with these commands - only conditional processes and loops are able to solve this problem. Consequentially XSLT needs such commands, and, of course, contains those. The following table contains these elements:
| xsl:for-each | This elements contains a template for a specified pattern (by the attribute select) and will process the existing node list by repeating the application of the template while the list has not reached its end. Therefore it can be seen as a loop. |
| xsl:if | This element is the XSLT counterpart to the standard if-clause, contained in every programming language. |
| xsl:choose | As xsl:if was the counterpart to the standard if-clause, xsl:choose is the counterpart to the well-known switch-clause. |
In the next code contains an example for all the three elements:
|
<!-- xsl:for-each --> <xsl:for-each select="/paragraph/section"> <xsl:element name="section"/> </xsl:for-each><!-- xsl:if --> <xsl:if test="/section/@name = 'kant'"> <xsl:message terminate="yes">the categoric imperativ</xsl:message> </xsl:if> <!-- xsl:choose --> <xsl:choose> <xsl:when test="/section/@name = 'kant'"> <xsl:message terminate="yes">the categoric imperativ</xsl:message> </xsl:when> <xsl:when test="/section/@name = 'adams'"> <xsl:message terminate="yes">hitch hike</xsl:message> </xsl:when> <xsl:otherwise> <xsl:message terminate="yes">unknown</xsl:message> </xsl:otherwise> </xsl:choose> |
The first example is a simple xsl:for-each element, which selects all sections of all paragraphs for its node list and creates a section element for each of them. It is followed by an xsl:if element; its condition for proceeding is the equality of the the attribute name in any section node and the string "kant". If the attribute and the string are equal, an XSLT message (xsl:message - please follow the link for more detailed information) will be put out and the further proceeding of the stylesheet is terminated - this is done by the xsl:message element, which has been unknown until now. The xsl:choose example uses the same condition as the xsl:if example, but in the second case with a different value. As already mentioned, it works like a switch-clause and therefore, it can contain an optional xsl:otherwise element, which handles the default case.
Additionally to the explained elements, XSLT contains some more features, among other things, elements for sorting (xsl:sort) and numbering (xsl:number) - please reference the links for information about them.
The code below is an example of a simple stylesheet (source: W3C):
|
At first the XML source code fragment:
|
|||||||||||||||||
|
<sales> <division id="North"> <revenue>10</revenue> <growth>9</growth> <bonus>7</bonus> </division> <division id="South"> <revenue>4</revenue><growth>3</growth> <bonus>4</bonus> </division> <division id="West"> <revenue>6</revenue> <growth>-1.5</growth> <bonus>2</bonus> </division> </sales> |
|||||||||||||||||
|
Then the XSLT stylesheet (for transforming into HTML):
|
|||||||||||||||||
|
<html xsl:version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" lang="en"> <head> <title>Sales Results By Division</title> </head> <body> <table border="1"> <tr> <th>Division</th> <th>Revenue</th> <th>Growth</th> <th>Bonus</th> </tr> <xsl:for-each select="sales/division"> <!-- order the result by revenue --> <xsl:sort select="revenue" data-type="number" order="descending"/> <tr> <td> <em><xsl:value-of select="@id"/></em> </td> <td> <xsl:value-of select="revenue"/> </td> <td> <!-- highlight negative growth in red --> <xsl:if test="growth < 0"> <xsl:attribute name="style"> <xsl:text>color:red</xsl:text> </xsl:attribute> </xsl:if> <xsl:value-of select="growth"/> </td> <td> <xsl:value-of select="bonus"/> </td> </tr> </xsl:for-each> </table> </body> </html> |
|||||||||||||||||
|
And now the HTML output:
|
|||||||||||||||||
|
<html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Sales Results By Division</title> </head> <body> <table border="1"> <tr> <th>Division</th><th>Revenue</th><th>Growth</th><th>Bonus</th> </tr> <tr> <td><em>North</em></td><td>10</td><td>9</td><td>7</td> </tr> <tr> <td><em>West</em></td><td>6</td><td style="color:red">-1.5</td><td>2</td> </tr> <tr> <td><em>South</em></td><td>4</td><td>3</td><td>4</td> </tr> </table> </body> </html> |
|||||||||||||||||
|
In a browser it would look like this:
|
|||||||||||||||||
|
For more detailed information about XSLT, please follow the links below.
| the XSLT definition |