如何在XSL中使用SUM和AVERAGE?

时间:2012-01-19 22:14:30

标签: xslt xslt-1.0

我想要每辆车的总公里数和每天的平均公里数

这是输入XML:

 <?xml version="1.0" encoding="ISO-8859-1" ?>   

 <output>   
<cars>  
   <car>    
      <id>1</id>    
      <brand>BMW</brand>    
      <type>M3</type>   
      <license>AD-9999-ATSR</license>   
   </car>   
<car>   
     <id>2</id> 
     <brand>Volkwagen</brand>   
     <type>GTI</type>   
     <license>ASD-7458-WERT</license>   
     </car> 
 </cars>    
 <distances>    
  <distance>    
    <id_car>1</id_car>  
    <date>20120118</date>   
    <distance>90</distance> 
</distance> 
 <distance> 
  <id_car>1</id_car>    
  <date>20120117</date> 
  <distance>23</distance>   
  </distance>
 <distance> 
  <id_car>1</id_car>    
  <date>20120117</date> 
  <distance>17</distance>   
  </distance>
<distance>  
  <id_car>1</id_car>    
 <date>20120116</date>  
 <distance>5</distance> 
 </distance>    
 <distance> 
 <id_car>2</id_car> 
<date>20120101</date>   
 <distance>92</distance>    
</distance> 
 <distance> 
 <id_car>2</id_car> 
 <date>20120102</date>  
 <distance>87</distance>    
 </distance>
 <distance> 
 <id_car>2</id_car> 
 <date>20120102</date>  
 <distance>13</distance>    
 </distance>    
<distance>  
 <id_car>2</id_car> 
 <date>20120103</date>  
 <distance>112</distance>   
  </distance>   
 </distances>   
</output>   

这是输出xml:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<output>
<cars>
<car>
  <id>1</id>
  <brand>BMW</brand>
  <type>M3</type>
  <license>AD-9999-ATSR</license>
    <distance Total_kM="135"></distance>
    <distance average_KM/day="18/90"></distance>
    <distance average_KM/day="17/20"></distance>
    <distance average_KM/day="16/5"></distance>
</car>
<car>
  <id>2</id>
  <brand>Volkwagen</brand>
  <type>GTI</type>
  <license>ASD-7458-WERT</license>
    <distance Total_kM="304"></distance>
    <distance averageKM/day="01/90"></distance>
    <distance average_KM/day="02/50"></distance>
    <distance average_KM/day="03/112"></distance>
</car>
</cars>
</output>

您可以在输出中想到这样或另外的安排,以显示每辆车的总公里数和每天的平均公里数

这是我想要更改的xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="distances" match="distance" use="id_car" />

    <xsl:template match="output">
        <xsl:apply-templates select="cars" />
    </xsl:template>

    <xsl:template match="car">
        <xsl:copy>
            <xsl:apply-templates />
            <distances>
                <xsl:apply-templates select="key('distances', id)" />
            </distances>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="distance">
        <distance day="{date}">
            <xsl:value-of select="distance" />
        </distance>
    </xsl:template>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

如何在XSL中使用SUM和AVERAGE输出我想要的内容?

感谢您的时间和精力

1 个答案:

答案 0 :(得分:2)

以下样式表会产生想要的结果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:key name="byCarId" match="distance" use="id_car"/>
    <xsl:key name="byCarIdAndDate" match="distance" 
             use="concat(id_car, '|', date)"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="car">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <distance Total_kM="{sum(key('byCarId', id)/distance)}"/>
            <xsl:apply-templates select="key('byCarId', id)"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template
        match="distance[generate-id()=
                        generate-id(key('byCarIdAndDate', 
                                        concat(id_car, '|', date))[1])]">
        <xsl:variable name="thisDate"
            select="key('byCarIdAndDate', concat(id_car, '|', date))"/>
        <xsl:variable name="sum" select="sum($thisDate/distance)"/>
        <xsl:variable name="count" select="count($thisDate)"/>
        <distance average_KM_day="{substring(date, 7, 2)}/{$sum div $count}"/>
    </xsl:template>
    <xsl:template match="distances|distance"/>
</xsl:stylesheet>

<强>解释

  • Identity Transform输出源
  • 中显示的每个car元素的大部分内容
  • 使用两个单独的钥匙:1)按每辆车的ID分组,2)按车辆ID和日期的组合分组
  • 每个可能的车辆ID和日期对只需要一个额外的模板来获取第一个distance,其中我们输出该组合的平均值