从一组数据XSL中获取平均值

时间:2015-09-30 23:58:36

标签: xml xslt

我有一个表(使用下面提供的XSL文档创建)。我需要获得每个月温度(最小值和最大值)和降雨量的平均数据。

我已经开始了这个但是我把模板搞得一团糟,想知道是否有人可以看看?我得到了一堆重复的标题,我认为不应该存在,而且我没有运气将数据拉到一起。

XSL文件:

<?xml version="1.0" encoding="UTF-8"?>

<!--
    Document   : weather.xsl
    Created on : September 30, 2015, 5:37 PM
    Author     : rory
    Description:
        Purpose of transformation follows.
-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>

    <xsl:variable name="year" select="2015"/>
    <xsl:variable name="x" select="//measurement[@year=$year]"/>
    <xsl:variable name="monthsOfYear" select="$x[@day=1]/month"/>
    <xsl:variable name="daysOfMonth" select="$x[@month=1]/day"/>
    <xsl:variable name="highestRainfall" select="$x/rainfall[.!=''][not( . &lt; $x/rainfall)]"/>
    <xsl:variable name="highestMinTemp" select="$x/temperature[@type='minimum' and .!=''][not( . &lt; $x/temperature[@type='minimum'])]" />
    <xsl:variable name="lowestMinTemp" select="$x/temperature[@type='minimum' and .!=''][not( $x/temperature[@type='minimum']  &lt; . )]" />
    <xsl:variable name="highestMaxTemp" select="$x/temperature[@type='maximum' and .!=''][not( . &lt; $x/temperature[@type='maximum'])]" />
    <xsl:variable name="lowestMaxTemp" select="$x/temperature[@type='maximum' and .!=''][not( $x/temperature[@type='maximum']  &lt; . )]" />
    <xsl:variable name="highestSolar" select="$x/solar[.!=''][not( . &lt; $x/solar)]"/>

    <!-- TODO customize transformation rules 
         syntax recommendation http://www.w3.org/TR/xslt 
    -->
    <xsl:template match="/">
        <html>
            <head>
                <title>Formatted Weather Outputs (Question 6)</title>

                <style>
                    .odd{
                        background: lightgreen;
                    }
                    .even{
                        background: violet;
                    }
                    .negative{
                        color: red;
                    }
                </style>
            </head>
            <body>
                <table border="1" style="text-align:center;border-collapse:collapse;">
                    <xsl:apply-templates select="weather" />
                </table>
                <table border="1" style="text-align:center;border-collapse:collapse;">
                    <xsl:apply-templates select="weather/measurement[@year='2015']" />
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="weather">
        <caption>Daily Observations</caption>
            <tr>
                <th>Date (DD/MM/YYYY)</th>
                <th>Min Temp (<sup>o</sup>C)</th>
                <th>Max Temp (<sup>o</sup>C)</th>
                <th>Solar Radiation (kwh/m<sup>2</sup>)</th>
                <th>Rainfall (mm)</th>
            </tr>

            <!-- Only display dates for 2015 -->
            <xsl:for-each select="measurement[@year='2015']">
                <tr>
                    <xsl:attribute name="class">
                        <xsl:choose>
                            <xsl:when test="(@month mod 2 != 0)">odd</xsl:when>
                            <xsl:otherwise>even</xsl:otherwise>
                        </xsl:choose>
                    </xsl:attribute>

                    <td>
                        <xsl:value-of select="concat(@day, '/', @month, '/', @year)" />
                    </td>
                    <td>
                        <xsl:attribute name="class">
                            <xsl:choose>
                                <xsl:when test="temperature[@type='minimum'] &lt; 0">negative</xsl:when>
                            </xsl:choose>
                        </xsl:attribute>
                        <xsl:if test=" temperature[@type='minimum'] = $highestMinTemp">
                            <xsl:attribute name="style">background-color:gold</xsl:attribute>
                        </xsl:if>
                        <xsl:if test=" temperature[@type='minimum'] = $lowestMinTemp">
                            <xsl:attribute name="style">background-color:lightblue</xsl:attribute>
                        </xsl:if>
                        <xsl:value-of select="temperature[@type='minimum']" />
                    </td>
                    <td>
                        <xsl:if test=" temperature[@type='maximum'] = $highestMaxTemp">
                            <xsl:attribute name="style">background-color:gold</xsl:attribute>
                        </xsl:if>
                        <xsl:if test=" temperature[@type='maximum'] = $lowestMaxTemp">
                            <xsl:attribute name="style">background-color:lightblue</xsl:attribute>
                        </xsl:if>    
                        <xsl:value-of select="temperature[@type='maximum']" />                                   
                    </td>
                    <td>
                        <xsl:if test=" solar = $highestSolar">
                            <xsl:attribute name="style">background-color:gold</xsl:attribute>
                        </xsl:if>
                        <xsl:value-of select="solar"/>
                    </td>
                    <td>
                        <xsl:if test=" rainfall = $highestRainfall">
                            <xsl:attribute name="style">background-color:gold</xsl:attribute>
                        </xsl:if>
                        <xsl:value-of select="rainfall" />
                    </td>
                </tr>
            </xsl:for-each>
    </xsl:template>

    <xsl:template match="weather/measurement">
        <xsl:variable name="totalMinTemp" select="sum(temperature[@type='minimum'])" />
        <xsl:variable name="numberOfDays" select="count(temperature[@type='minimum'])" />
        <xsl:variable name="averageMinTemp" select="($totalMinTemp div $numberOfDays)" />
        <xsl:variable name="month" select="@month" />
        <caption>Monthly Averages</caption>
            <tr><td colspan="4">Average</td></tr>
            <tr>
                <td>Month</td><td>Min Temp<sup>o</sup>C</td><td>Max Temp<sup>o</sup>C</td><td>Solar radiation kwh/m<sup>2</sup></td>
            </tr>
            <tr>
                <td><!--<xsl:value-of select="$month" />-->T</td>
            </tr>

    </xsl:template>

</xsl:stylesheet>

输入文件样本:

<weather>
    <measurement year="2015" month="09" day="19">
        <rainfall>0.0</rainfall>
        <temperature type="minimum">5.2</temperature>
        <temperature type="maximum">19.9</temperature>
        <solar>5.0</solar>
    </measurement>
    <measurement year="2015" month="09" day="20">
        <rainfall>0.0</rainfall>
        <temperature type="minimum">5.3</temperature>
        <temperature type="maximum">22.7</temperature>
        <solar>5.3</solar>
    </measurement>
    <measurement year="2015" month="09" day="21">
        <rainfall>0.0</rainfall>
        <temperature type="minimum">6.9</temperature>
        <temperature type="maximum">17.6</temperature>
        <solar>3.8</solar>
    </measurement>
</weather>

1 个答案:

答案 0 :(得分:0)

执行此操作时:

<xsl:template match="weather/measurement">
        <xsl:variable name="totalMinTemp" select="sum(temperature[@type='minimum'])" />

您正在处理一个测量,并且它只有一个@ type = minimum的温度,因此单个集合的总和通常是该值。我怀疑你想要总结一个月或一年的所有测量结果,当你处理个人测量时你不能这样做。

如果您可以使用XSLT 2.0,那么您将要编写类似

的内容
<xsl:template match="weather">
  ...
  <xsl:for-each-group select="measurement[@year='2015']" group-by="@month">
    <xsl:variable name="totalMinTemp" select="sum(current-group()/temperature[@type='minimum'])" />
    <xsl:variable name="numberOfDays" select="count(current-group()/temperature[@type='minimum'])" />
     ....

正如我之前提到的,在XSLT 1.0中进行分组比较棘手:您需要阅读&#34; Muenchian分组&#34;大多数优秀的XSLT教科书都涵盖了这一点,并且还有大量的在线资源。