Ignoring all your existing logic, I think the summary can be done something
like this:
<xsl:for-each-group select="//entry" group-by="statistics_category">
<xsl:value-of select="current-grouping-key(), ': ',
format-number(sum(current-group()/f:duration-in-hours(.), '0.00'))"/>
</xsl:for-each-group>
<xsl:function name="f:duration-in-hours" as="xs:double" >
<xsl:param name="entry" as="element(entry)"/>
<!-- TODO: add logic for the case where there's no following-siblng -->
<xsl:variable name="this" select="dateTime(/isodate, time)"/>
<xsl:variable name="next" select="dateTime(following-sibling::entry/isodate,
following-sibling::entry/time)"/>
<xsl:sequence select="($next - $this) div xs:duration('PT1H')"/>
</xsl:function>
Michael Kay
Saxonica
On 26 Aug 2013, at 17:33, Raimund Kammering wrote:
Hi,
i need to build up two tables listing periods between timestamps plus some
categories. I got the math with evaluating the time periods running but am
stuck on building additionally a summary table for the appearances of the
categories. Here is what I have:
XML:
-------
<list>
<url_base>/2013/06/09.02_n</url_base>
<entry>
<severity>STATISTICS</severity>
<isodate>2013-02-09</isodate>
<time>23:00:00</time>
<statistics_category>Delivery</statistics_category>
</entry>
<entry>
<severity>STATISTICS</severity>
<isodate>2013-02-10</isodate>
<time>00:37:33</time>
<statistics_category>Tuning</statistics_category>
<tuning>Problems</tuning>
</entry>
<entry>
<severity>STATISTICS</severity>
<isodate>2013-02-10</isodate>
<time>02:59:03</time>
<statistics_category>Delivery</statistics_category>
</entry>
<entry>
<severity>STATISTICS</severity>
<isodate>2013-02-10</isodate>
<time>03:27:39</time>
<statistics_category>Tuning</statistics_category>
<tuning>Quality</tuning>
</entry>
<entry>
<severity>STATISTICS</severity>
<isodate>2013-02-10</isodate>
<time>03:42:09</time>
<statistics_category>Delivery</statistics_category>
</entry>
<entry>
<severity>STATISTICS</severity>
<isodate>2013-02-10</isodate>
<time>04:18:11</time>
<statistics_category>Down</statistics_category>
<down>RF</down>
</entry>
</list>
XSL:
-------
<xsl:param name="url_base">
<xsl:value-of select="/list/url_base"/>
</xsl:param>
<xsl:template name="statistics_details">
<table>
<tr><td colspan="3">Detailed statistics</td></tr>
<tr><td></td><td></td><td>Start</td><td>End</td><td>duration
[hours]</td><td>Category</td><td>Reason</td></tr>
<xsl:for-each select="entry[severity!='DELETE']/statistics_category">
<xsl:sort order="descending" select="../isodate"/>
<xsl:sort order="descending" select="../time"/>
<xsl:variable name="end_time">
<xsl:choose>
<xsl:when
test="ancestor::entry/following-sibling::entry[severity!='DELETE']/statistics_category">
<!-- FIXME - will fail if two or more consecutive deletes follow!
-->
<xsl:value-of
select="ancestor::entry/following-sibling::entry[severity!='DELETE']/statistics_category/../time"/>
</xsl:when>
<!-- last log -->
<xsl:otherwise>
<xsl:choose>
<xsl:when test="substring($url_base, string-length($url_base)
)='M'">
<xsl:value-of select="'15:00:00'"/>
</xsl:when>
<xsl:when test="substring($url_base, string-length($url_base)
)='a'">
<xsl:value-of select="'23:00:00'"/>
</xsl:when>
<xsl:when test="substring($url_base, string-length($url_base)
)='n'">
<xsl:value-of select="'07:00:00'"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>ERROR: Could not determine shift end</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="end_date">
<xsl:choose>
<xsl:when
test="ancestor::entry/following-sibling::entry[severity!='DELETE']/statistics_category">
<!-- FIXME - will fail if two or more consecutive deletes follow!
-->
<xsl:value-of
select="ancestor::entry/following-sibling::entry[severity!='DELETE']/statistics_category/../isodate"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="substring($url_base, string-length($url_base)
)='M'">
<xsl:value-of select="substring-before(date:date(),'+')"/>
</xsl:when>
<xsl:when test="substring($url_base, string-length($url_base)
)='a'">
<xsl:value-of select="substring-before(date:date(),'+')"/>
</xsl:when>
<xsl:when test="substring($url_base, string-length($url_base)
)='n'">
<xsl:choose>
<xsl:when test="substring(../time, 1, 1)!='0'">
<xsl:call-template name="date:add">
<xsl:with-param name="date-time" select="../isodate" />
<xsl:with-param name="duration" select="'P1D'" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../isodate"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before(date:date(),'+')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="start_time" select="../time"/>
<xsl:variable name="end" select="concat($end_date, 'T', $end_time)"/>
<xsl:variable name="start" select="concat(../isodate, 'T',
$start_time)"/>
<xsl:variable name="time-diff-dur">
<xsl:call-template name="date:difference">
<xsl:with-param name="start" select="$start" />
<xsl:with-param name="end" select="$end" />
</xsl:call-template>
</xsl:variable>
<!-- The above returns a duration formatted string, so convert that to
seconds: -->
<xsl:variable name="time-diff-sec">
<xsl:call-template name="duration2seconds">
<xsl:with-param name="duration" select="$time-diff-dur" />
</xsl:call-template>
</xsl:variable>
<tr>
<td></td><td></td>
<td><xsl:value-of select="$start_time"/></a></td>
<td><xsl:value-of select="$end_time"/></td>
<td><xsl:value-of select="format-number($time-diff-sec div 3600,
'0.00')"/></td>
<td><xsl:value-of select="."/></td>
<xsl:choose>
<xsl:when test=".='Tuning'">
<td><xsl:value-of select="../Tuning"/></td>
</xsl:when>
<xsl:when test=".='Down'">
<td><xsl:value-of select="../Down"/></td>
</xsl:when>
<xsl:otherwise>
<td></td></xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</xsl:template>
HTML Output:
-------------------
Detailed statistics
Start End duration [hours] Category
04:18:11 07:00:00 2.70 Down RF
03:42:09 04:18:11 0.60 Delivery
03:27:39 03:42:09 0.24 Tuning Quality
02:59:03 03:27:39 0.48 Delivery
00:37:33 02:59:03 2.36 Tuning Problems
23:00:00 00:37:33 1.63 Delivery
I completely omit here the stuff needed for the time difference calculation
etc., since this all works just fine and is quite impressive - thanks to the
xsl-list's previous help!! But now I would like to have above the 'Detailed
statistics' section a 'Statistics Summary' showing the sums for the
statistics categories. So that the final html would look like this:
Desired HTML Output:
------------------------------
Statistics Summary
Delivery: 2.71 Tuning: 2.60 Down: 2.70
Detailed statistics
Start End duration [hours] Category
04:18:11 07:00:00 2.70 Down RF
03:42:09 04:18:11 0.60 Delivery
03:27:39 03:42:09 0.24 Tuning Quality
02:59:03 03:27:39 0.48 Delivery
00:37:33 02:59:03 2.36 Tuning Problems
23:00:00 00:37:33 1.63 Delivery
I thought of several of the 'standard trick' like recursion and/or calling
template with modes, but never got a clear picture how to manage it (this
nasty thing with the needed relation between the two consecutive 'entry'
elements …). Any idea on how to approach this would be greatly welcome!!
And yes some of the calling logic I left out, since this is not the tricky
part and the above should hopefully sketch the problem sufficiently (and for
simplicity I left out the case of an entry having severity='DELETE' ;-)!?
Cheers,
Raimund
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--