问题
I want to the total kilometers per car and the average kilometers per day
This is the input 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>
This is the 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>
Something like this or onother arangement you can think of ,in the output, to show the total kilometers per car and the average kilometers per day
This is the xsl that i am trying to change :
<?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>
How do I use SUM and AVERAGE in XSL to ouput what i want ?
Thank you for your time and effort
回答1:
The following stylesheet produces the wanted result:
<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>
Explanation:
- The Identity Transform outputs most of each
car
element as it appears in the source - Two separate keys are used: 1) to group by each car's ID and 2) to group by the combination of car ID and date
- Only one additional template is needed to grab the first
distance
for each possible car ID and date pair, in which we output the average for that combination
来源:https://stackoverflow.com/questions/8934166/how-do-i-use-sum-and-average-in-xsl