Imagine we have this XML data:
<flights> <flight> <number>101</number> <destination>New York</destination> <date>01/06/08</date> <time>11:00</date> </flight> </flights>How might we transform this XML data to HTML using XSLT?
The XSLT stylesheet consists of a series of processing instructionswhich describe how to convert the input XML to the output format. Here is an example to transform the above data to an HTML page:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>XSLT test</title> </head> <body> <h1>Solent Airways!</h1> Number: <xsl:value-of select="/flights/flight/number" /> <br/> Time: <xsl:value-of select="/flights/flight/time" /> <br/> Destination: <xsl:value-of select="/flights/flight/destination" /> <br/> </body> </html> </xsl:template> </xsl:stylesheet>
Notice how the XSL stylesheet contains a mixture of:
Notice how we use expressions such as:
<xsl:value-of select="/flights/flight/number"/>to read in data from the input XML. This means:
The
/flights/flight/numberis known as an XPath expression. XPath is a syntax for locating particular tags within XML data, and is used extensively within XSLT.
To link the XSLT to the input XML document, we have to specify it within an xml-stylesheet line within the input XML, as follows:
<?xml version='1.0'?> <?xml-stylesheet type='text/xsl' href='XSLT.xsl'?> <flights> <flight> <number>101</number> <destination>New York</destination> <date>01/06/08</date> <time>11:00</date> </flight> </flights>where XSLT.xsl is the XSLT file being used to transform this data.
We can also loop through several items of data in the input XML with XSLT, and therefore transform several items of input data with one XSL stylesheet. For example imagine we have this XML data representing all the flights to New York on 01/06/08:
<flights> <flight> <number>101</number> <destination>New York</destination> <date>01/06/08</date> <time>11:00</date> </flight> <flight> <number>103</number> <destination>New York</destination> <date>01/06/08</date> <time>13:00</date> </flight> <flight> <number>105</number> <destination>New York</destination> <date>01/06/08</date> <time>15:00</date> </flight> </flights>
The XSLT to transform this whole set of data would be:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/flights"> <html> <head> <title>test</title> </head> <body> <h1>Flights</h1> <xsl:for-each select="flight"> Number: <xsl:value-of select="number" /> <br/> Destination: <xsl:value-of select="destination" /> <br/> Date: <xsl:value-of select="date" /> <br/> Time: <xsl:value-of select="time" /> <br/> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>
The loop begins with the line:
<xsl:for-each select="flight">This means loop through each flight tag in the input XML. Everything between xsl:for-each and /xsl:for-each will be done for each flight tag.
Within the for-each loop we display the individual details about the current flight, i.e. its flight number, destination, date and time. Note how now we just say:
<xsl:value-of select="number"/>rather than the full path to the number tag, i.e.:
<xsl:value-of select="flights/flight/number"/>This is because we are already inside the flight tag (because the for-each loop is looping through each flight tag.
Note also the line near the top:
<xsl:template match="/flights">This indicates that what follows is a template for the flights tag in the input XML: in other words, the flights tag in the input XML will be replaced using the instructions between <xsl:template> and </xsl:template>.
It follows from this that because we are already within the template for <flights>, the for-each loop which loops through each flight tag just needs to indicate flight, not flights/flight
We can also specify conditions in XSLT. For instance the line:
<xsl:for-each select="flight[seats>0]">will only select those flights in the input XML for which the value of the <seats> tag within the flight tag is greater than 0.
The choose/when statement allows us to choose between one of a number of options depending on the values in the input XML data, e.g.:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/flights">
<html>
<head>
<title>test</title>
</head>
<body>
<h1>Solent Airways Flights</h1>
<!-- How to do a conditional statement. Different XHTML is generated
depending on whether the flight has seats or not. -->
<xsl:for-each select="flight">
<xsl:choose>
<xsl:when test="seats > 0">
<xsl:value-of select="number" /> has seats
<br/>
</xsl:when>
<xsl:when test="seats=0">
<xsl:value-of select="number" /> has no free seats
<br/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
This XSL stylesheet is performing different transformations depending on the value of the <seats> tag within the current <flight> tag. If the flight has seats (xsl:when test="seats> 0"), the user is informed of this in the output HTML. (Note the need to use > rather than > - this is because > is used to close a tag).
If the flight has no free seats, the user is also informed of this.