Finished XSLT Example Using Variables

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Finished XSLT Example Using Variables

The following XSLT file is the result of creating the template rules described in the previous topics in this section.

Example

This example uses variables and passes parameters between template rules.

XML File (weatherlog.xml)

Use weatherlog.xml, in Initial XSLT Example Using Variables. Change the href attribute to reference weatherlog.xsl.

XSLT File (weatherlog.xsl)

<?xml version="1.0" ?>
<!-- Declare a character entity for displaying the
    "degrees" symbol to be used in temperature readings. -->
<!DOCTYPE xsl:stylesheet [
<!ENTITY degrees "&#176;">
]>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40">

<!-- Global parameter for selecting a local. -->
<xsl:param name="place_param" select="'[All]'"/>

<!-- Template rule for document root: basic Web page setup. -->    
<xsl:template match="/">
    <HTML>
        <HEAD>
            <TITLE>Weather Readings</TITLE>
            <STYLE type="text/css">
                h1 {background-color: gold;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 24pt}
                h2 {background-color: yellow;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 18pt}
                h3 {background-color: teal;
                    font-family: Tahoma,Verdana,Arial,sans-serif;
                    font-size: 14pt;
                    font-weight: bold;
                    text-align: center}
                th {background-color: silver;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                td {background-color: white;
                    font-family: Tahoma,Verdana,Arial,sans-serif}
                .locale {width: 500;
                    border: 1px;
                    border-style: solid;
                    margin: 10px}
            </STYLE>
        </HEAD>
        <BODY>
            <xsl:apply-templates/>
        </BODY>
    </HTML>
</xsl:template>

<!-- Override built-in template rule for text nodes
    (suppress any text unless explicitly requested). -->
<xsl:template match="text()"/>

<!-- Named template rule "placename" returns informative name of
    a locale, given known generic values of "location1," and so on. -->
<xsl:template name="placename">
    <xsl:param name="location" select="'[Unknown Locale]'"/>
    <xsl:choose>
        <xsl:when test="$location='location1'">Midtown</xsl:when>
        <xsl:when test="$location='location2'">Northeast</xsl:when>
        <xsl:when test="$location='location3'">Airport</xsl:when>
        <xsl:otherwise>[Unknown Locale]</xsl:otherwise>
    </xsl:choose>
</xsl:template>    

<!-- Template rule for root <weather> element. -->
<xsl:template match="weather">
    <!-- Set up major page heading, depending on value of global
        parameter "place_param". -->
    <h1>Weather Readings for
        <xsl:choose>
            <xsl:when test="$place_param = '[All]'">
                All Available Locations
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="placename">
                    <xsl:with-param name="location" select="$place_param"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </h1>
    <!-- Process <day> children of <weather> element. -->
    <xsl:for-each select="day">
        <!-- Variable "average_temp" holds formatted version of average
            high temperature, across all locales for a given day. -->
        <xsl:variable name="average_temp" 
            select="format-number(sum(locale/temp/high) div count(locale), '##0.00')"/>
        <h2>As of <xsl:value-of select="@date"/></h2>
        <xsl:choose>
            <!-- If global parameter "place_param" is the default "[All]", 
                process all <locale> children of the <day> element... -->
            <xsl:when test="$place_param = '[All]'">
                <xsl:apply-templates select="locale"/>
            </xsl:when>
            <!-- ...otherwise, filter the <locale> children of the <day>
                element, selecting only those matching the requested 
                locale. -->
            <xsl:otherwise>
                <xsl:apply-templates select="locale[@place=$place_param]"/>
            </xsl:otherwise>
        </xsl:choose>
        <!-- If processing all locales (per "place_param" global
             parameter), add a block displaying the average high 
             temperature across all locales. -->
        <xsl:if test="$place_param = '[All]'">
            <div class="locale">
                <table align="center" width="400">
                    <tr>
                        <td>Average High Temperature for <xsl:value-of select="@date"/>, All Locales:</td>
                        <td>
                            <xsl:value-of select="$average_temp"/>
                            &degrees; <xsl:text> </xsl:text><xsl:value-of select="../@temp_scale"/>
                        </td>
                    </tr>
                </table>
            </div>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<!-- Template rule for <locale> elements: set up a label for the
    locale (using "informative" form of location name returned
    by the "placename" named template, followed by a table of
    this locale's weather readings. -->        
<xsl:template match="locale">
    <div class="locale">
        <h3>
            <xsl:call-template name="placename">
                <xsl:with-param name="location" select="@place"/>
            </xsl:call-template>
        </h3>
        <table align="center">
            <tr>
                <th>Temp Range</th>
                <th>Wind</th>
                <th>Barometer</th>
                <th>Humidity</th>
                <th>Precipitation</th>
            </tr>
            <tr>
                <td align="center">
                    <xsl:value-of select="concat(temp/low, '-', temp/high)"/>
                    &degrees; <xsl:text> </xsl:text><xsl:value-of select="/weather/@temp_scale"/>
                </td>
                <td align="center">
                    <xsl:value-of select="concat(wind_speed, ' ', wind_speed/@units)"/>
                    <xsl:value-of select="concat(' from ', wind_dir)"/>
                </td>
                <td align="center">
                    <xsl:value-of select="concat(barom, barom/@units)"/>
                </td>
                <td align="right">
                    <xsl:value-of select="concat(string(rel_humid * 100), '%')"/>
                </td>
                <td align="right">
                    <xsl:value-of select="concat(precip, ' ', precip/@units)"/>
                </td>
            </tr>
        </table>
    </div>
</xsl:template>

</xsl:stylesheet>

Formatted Output