XML - Managing Data Exchange/C.5
XML Style Sheet
editSimilar to the layout we visited in chapter 3, this style sheet lists each hotel in the XML document by country. But this time some new features have been added. Price range elements have been included, each hotel’s amenities are now listed, and the population of each country has been formatted to improve readability.
XSLT Functions
editWhen formatting XML output, there may be times when you might want to massage the data or get certain values for display. Placed within the XML style sheet, functions can be used to manipulate data during the transformation. We saw an example of this in chapter 3 when displaying the number of hotels within a city.
In order to make the population a little easier to read in our style sheet, we need to separate the digits into groups of threes and add commas. To do this we use the format-number( ) function. The purpose of this function is to convert a numeric value into a string using specified patterns that control the number of leading zeroes, separator between thousands, etc. The basic syntax of this function is as follows:
- number is the numeric value to be formatted
- pattern is a string that lays out the general representation of a number. Each character in the string represents either a digit from number or some special punctuation such as a comma or minus sign.
In order to display <population> with the digits grouped by three’s using commas as the separator, the format-number function was used in line {51} of our XML style sheet.
The following are the characters and their meanings used to represent the number format when using the format-number function within a style sheet:
Symbol | Meaning |
0 |
A digit. |
There are numerous other functions that you may find use for within a style sheet. The following are some additional numeric based functions that are useful when handling numbers within a stylesheet.
Name | Description |
ceiling() | Returns the smallest integer that is not less than the number argument |
floor() | Returns the largest integer that is not greater than the number argument |
number() | Converts the value argument to a number |
round() | Rounds the number argument to the nearest integer |
sum() | Returns the total value of a set of numeric values in a node-set |
<?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"/> <xsl:template match="/"> <HTML> <HEAD> <TITLE>World Renowned Hotels</TITLE> <STYLE TYPE="text/css"> H2 {TEXT-ALIGN:CENTER;} .blueBackground {BACKGROUND-COLOR:LIGHTBLUE; COLOR:BLACK; TEXT-ALIGN:LEFT; BORDER-WIDTH:0px; WIDTH:90%;} .blackBackground {BACKGROUND-COLOR:BLACK; TEXT-ALIGN:LEFT; COLOR:WHITE; FONT-SIZE:12pt; BORDER-WIDTH:2px;} </STYLE> </HEAD> <BODY> <H2>* * * Hotels Listings by Country * * *</H2> <xsl:apply-templates select="tourGuide"/> </BODY> </HTML> </xsl:template> <xsl:template match="tourGuide"> <xsl:for-each select="city"> <TABLE CLASS="blackBackground"> <TR> <TD> <BR/> <TABLE style="width:90%; color:white;" align="center"> <TR> <TD> <BR/> <b> <xsl:text>City: </xsl:text> </b> </TD> <TD> <BR/> <xsl:value-of select="cityName"/> </TD> </TR> <TR> <TD> <b> <xsl:text>History: </xsl:text> </b> </TD> <TD> <xsl:value-of select="history"/> </TD> </TR> <TR> <TD> <BR/> <b> <xsl:text>Country: </xsl:text> </b> </TD> <TD> <BR/> <xsl:value-of select="country"/> </TD> </TR> <TR> <TD> <b> <xsl:text>Population: </xsl:text> </b> <BR/> <BR/> </TD> <TD> <xsl:value-of select="format-number(population, '#,###,##0')"/> <BR/> <BR/> </TD> </TR> </TABLE> </TD> </TR> <TR> <TD colspan="2"> <center> <font style="font-size:medium">Hotels:</font> <br/> <xsl:for-each select="hotel"> <TABLE CLASS="blueBackground"> <TR> <TD STYLE="FONT-SIZE:8pt;width:20%;"> <IMG> <xsl:attribute name="SRC"> <xsl:value-of select="hotelPicture/@filename"/> </xsl:attribute> <xsl:attribute name="WIDTH"> <xsl:value-of select="hotelPicture/@size"/> </xsl:attribute> <xsl:attribute name="HEIGHT"> <xsl:value-of select="hotelPicture/@size"/> </xsl:attribute> <xsl:attribute name="ALT"> <xsl:value-of select="hotelPicture/@value"/> </xsl:attribute> </IMG> <BR/> </TD> <TD align="left" style="FONT-SIZE:10pt;"> <HR width="90%"/> <b> <xsl:text>Hotel Name: </xsl:text> </b> <xsl:value-of select="hotelName"/> <BR/> <b> <xsl:text>Street Address: </xsl:text> </b> <xsl:value-of select="streetAddress"/> <BR/> <b> <xsl:text>Telephone Number: </xsl:text> </b> <xsl:value-of select="telephoneNumber"/> <BR/> <b> <xsl:text>Email Address: </xsl:text> </b> <xsl:value-of select="emailAddress"/> <BR/> <b> <xsl:text>Price Range: $</xsl:text> </b> <xsl:value-of select="lowerPrice"/> - <xsl:value-of select="upperPrice"/> <BR/> <b> <xsl:text>Hotel Rating: </xsl:text> </b> <xsl:value-of select="hotelRating"/> <BR/> <b> <xsl:text>Amenities: </xsl:text> </b> <xsl:for-each select="amenities"> <xsl:value-of select="amenity"/> <xsl:if test="position() < last()"> <xsl:text>, </xsl:text> </xsl:if> </xsl:for-each> <HR width="90%"/> </TD> </TR> </TABLE> <BR/> </xsl:for-each> </center> </TD> </TR> </TABLE> </xsl:for-each> </xsl:template> </xsl:stylesheet>
Figure 5-5 XML stylesheet – amenity.xsl
In the XML stylesheet, you will see two additional functions position() and last(). The position function returns the position of the current context node in the current context node-set. The last function returns the index number of the last node in the context. To list each amenity for each hotel, the transformation checks to see if the current position of the node is different than the position of the last context node in the set. If this returns true, then a comma is added as the amenities are listed.
Although this stylesheet builds upon the one we saw in chapter 3, notice the use of embedded tables to further specify the layout of the data being conveyed. Values and their indicators have been separated into table cells, allowing for a cleaner look and feel.