XML - Managing Data Exchange/C.5

XML Style Sheet

edit

Similar 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

edit

When 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.

<xsl:value-of select="count(hotel)" />

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:

format-number (number, pattern)
  • 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
  #
  .
  ,
  ;
  -
  %
  X
  ‘

A digit.
A digit, zero shows as absent.
(period) Placeholder for decimal separator.
Placeholder for grouping separator.
Separate formats.
Default prefix for negative.
Multiply by 100 and show as a percentage.
Any other characters can be used in the prefix or suffix.
Used to quote special characters in a prefix or suffix.


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() &lt; 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.