I created an XLT document with an array of values for each of the hour of the day. I loop through this array by creating a variable using node-set.
I have a key created that holds the total counts for each hour called key-hours
. However, when I pass it a value from the $hour-array
variable, it does not display the corresponding total count.
XML data
<Records reportTime24h="18:14" reportTime="06:14:55PM" reportDate="2020-11-12" reportTitle="Samples per time of day v2">
<vars>
<date>2020-11-12</date>
</vars>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>07 AM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>08 AM</RegisterHour>
<Total>15</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>08 AM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>08 AM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Chemistry Plasma</TubeName>
<RegisterHour>08 AM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>09 AM</RegisterHour>
<Total>23</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>09 AM</RegisterHour>
<Total>15</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>09 AM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>09 AM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>09 AM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>09 AM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>10 AM</RegisterHour>
<Total>25</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>10 AM</RegisterHour>
<Total>8</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>10 AM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>11 AM</RegisterHour>
<Total>30</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>11 AM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>11 AM</RegisterHour>
<Total>18</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>11 AM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>11 AM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>11 AM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>3</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>29</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>24</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>3</Total>
</Record>
<Record>
<TubeName>Chemistry Plasma</TubeName>
<RegisterHour>12 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>01 PM</RegisterHour>
<Total>32</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>01 PM</RegisterHour>
<Total>33</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>01 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>01 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>01 PM</RegisterHour>
<Total>5</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>01 PM</RegisterHour>
<Total>3</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>36</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>13</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>38</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>8</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>Chemistry Plasma</TubeName>
<RegisterHour>02 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>23</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>29</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>12</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>5</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>5</Total>
</Record>
<Record>
<TubeName>Chemistry Plasma</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>3</Total>
</Record>
<Record>
<TubeName>Chemistry Urine</TubeName>
<RegisterHour>03 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>FAST_PLA</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>6</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>16</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>17</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Chemistry Plasma</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>2HR_PLASMA</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>1HR_PLASMA</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Chemistry Urine</TubeName>
<RegisterHour>04 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Chemistry Plasma</TubeName>
<RegisterHour>05 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>05 PM</RegisterHour>
<Total>3</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>05 PM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>06 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>06 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>09 PM</RegisterHour>
<Total>5</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>09 PM</RegisterHour>
<Total>4</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>10 PM</RegisterHour>
<Total>11</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>10 PM</RegisterHour>
<Total>11</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>10 PM</RegisterHour>
<Total>1</Total>
</Record>
<Record>
<TubeName>Wholeblood Haematology</TubeName>
<RegisterHour>11 PM</RegisterHour>
<Total>2</Total>
</Record>
<Record>
<TubeName>Chemistry Serum</TubeName>
<RegisterHour>11 PM</RegisterHour>
<Total>3</Total>
</Record>
<Record>
<TubeName>Chemistry Wholeblood</TubeName>
<RegisterHour>11 PM</RegisterHour>
<Total>1</Total>
</Record>
</Records>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="key-tube" match="Record" use="TubeName"/>
<xsl:key name="key-hour" match="Record" use="RegisterHour"/>
<xsl:key name="key-tube-hour" match="Record" use="concat(TubeName,'::',RegisterHour)"/>
<xsl:key name="key-hour-list" match="RegisterHour" use="."/>
<xsl:key name="key-tube-list" match="TubeName" use="."/>
<!--<xsl:variable name="unique-hour-list" select="//RegisterHour[generate-id() = generate-id(key('key-hour-list', .)[1])]"/>-->
<xsl:variable name="unique-tube-list" select="//TubeName[generate-id() = generate-id(key('key-tube-list', .)[1])]"/>
<!--Hour Array -->
<xsl:variable name="hours">
<hour>01 AM</hour>
<hour>02 AM</hour>
<hour>03 AM</hour>
<hour>04 AM</hour>
<hour>05 AM</hour>
<hour>06 AM</hour>
<hour>07 AM</hour>
<hour>08 AM</hour>
<hour>09 AM</hour>
<hour>10 AM</hour>
<hour>11 AM</hour>
<hour>12 AM</hour>
<hour>01 PM</hour>
<hour>02 PM</hour>
<hour>03 PM</hour>
<hour>04 PM</hour>
<hour>05 PM</hour>
<hour>06 PM</hour>
<hour>07 PM</hour>
<hour>08 PM</hour>
<hour>09 PM</hour>
<hour>10 PM</hour>
<hour>11 PM</hour>
<hour>12 PM</hour>
</xsl:variable>
<xsl:variable name="hour-array" select="exsl:node-set($hours)" xmlns:exsl="http://exslt.org/common"/>
<xsl:template match="/Records">
<html>
<head>
<title>
<xsl:value-of select="/Records/@reportTitle"/>_<xsl:value-of select="/Records/vars/date"/>
</title>
<style>
body { font-family: monospace; }
table { border-collapse: collapse; font-size: 8pt; width: 100%; }
td,th { padding: 3px; border: 1px solid gainsboro;}
th.day { width: 25px; }
h1,h2,h3,h4,h5 { margin: 0 0 5px 0; }
h3 { color: gray; }
thead,tfoot { background-color: whitesmoke; }
tbody th,
tbody td { text-align: right; }
tbody td.test { text-align: left; }
tbody td.area { text-align: left; font-weight: bold; text-decoration: underline; }
img.logo { float: right; width: 70px; }
header { clear:both; margin-bottom: 10px; border-bottom: 1px solid gray; padding-bottom: 10px;}
tfoot th { text-align:right;}
.red-10 {background-color: #F3DFDB}
.red-30 {background-color: #F1C8BF}
.red-50 {background-color: #EE8873}
.red-70 {background-color: #EF6E53}
.red-90 {background-color: #EB411E}
</style>
</head>
<body>
<h1><xsl:value-of select="/Records/@reportTitle"/></h1>
<h3><xsl:value-of select="/Records/vars/date"/> </h3>
<table>
<thead>
<tr>
<th style="text-align:left">Time of Day</th>
<xsl:apply-templates select="$unique-tube-list" mode="day-list"/>
<th>Total</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="$hour-array" mode="test-list"/>
</tbody>
<tfoot>
<tr>
<th>Totals</th>
<xsl:apply-templates select="$unique-tube-list" mode="day-totals"/>
<th>
<xsl:value-of select="format-number(sum(Record/Total),'###,###')" />
</th>
</tr>
</tfoot>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="TubeName" mode="day-list">
<th class="day"><xsl:value-of select="."/></th>
</xsl:template>
<xsl:template match="TubeName" mode="day-totals">
<th><xsl:value-of select="format-number(sum(key('key-tube',.)/Total),'###,###')"/></th>
</xsl:template>
<xsl:template match="hour" mode="test-list">
<xsl:variable name="h" select="."/>
<xsl:variable name="grand-total" select="sum(/Records/Record/Total)" />
<xsl:variable name="row-total" select="sum(key('key-hour',.)/Total)" />
<xsl:variable name="pct" select="($row-total div $grand-total)*100" />
<tr>
<xsl:choose>
<xsl:when test="$pct > 50">
<xsl:attribute name="class">red-90</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 40">
<xsl:attribute name="class">red-70</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 30">
<xsl:attribute name="class">red-50</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 20">
<xsl:attribute name="class">red-30</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 10">
<xsl:attribute name="class">red-10</xsl:attribute>
</xsl:when>
</xsl:choose>
<td class="test">
<xsl:value-of select="$h"/> (<xsl:value-of select="key('key-hour',$h)"/>)
</td>
<xsl:for-each select="$unique-tube-list">
<xsl:variable name="total" select="key('key-tube-hour',concat(current(),'::',$h))/Total"/>
<xsl:choose>
<xsl:when test="$total">
<td><xsl:value-of select="format-number($total,'###,###')" /></td>
</xsl:when>
<xsl:otherwise>
<td>0</td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<td>
<xsl:value-of select="format-number(sum(key('key-hour',$h)/Total),'###,###')" />
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
This results in the total column not been populated with the actual sum of totals. Here is what that looks like.
Here is a fiddle of the result for you to play with. https://xsltfiddle.liberty-development.net/pNvtBGk
I would suggest to change the context by doing
<xsl:template match="hour" mode="test-list">
<xsl:apply-templates select="$main-doc" mode="test-list">
<xsl:with-param name="h" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/" mode="test-list">
<xsl:param name="h"/>
<xsl:variable name="grand-total" select="sum(/Records/Record/Total)" />
<xsl:variable name="row-total" select="sum(key('key-hour', $h)/Total)" />
<xsl:variable name="pct" select="($row-total div $grand-total)*100" />
<tr>
<xsl:choose>
<xsl:when test="$pct > 50">
<xsl:attribute name="class">red-90</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 40">
<xsl:attribute name="class">red-70</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 30">
<xsl:attribute name="class">red-50</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 20">
<xsl:attribute name="class">red-30</xsl:attribute>
</xsl:when>
<xsl:when test="$pct > 10">
<xsl:attribute name="class">red-10</xsl:attribute>
</xsl:when>
</xsl:choose>
<td class="test">
<xsl:value-of select="$h"/> (<xsl:value-of select="key('key-hour',$h)"/>)
</td>
<xsl:for-each select="$unique-tube-list">
<xsl:variable name="total" select="key('key-tube-hour',concat(current(),'::',$h))/Total"/>
<xsl:choose>
<xsl:when test="$total">
<td><xsl:value-of select="format-number($total,'###,###')" /></td>
</xsl:when>
<xsl:otherwise>
<td>0</td>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<td>
<xsl:value-of select="format-number(sum(key('key-hour',$h)/Total),'###,###')" />
</td>
</tr>
</xsl:template>
Needs <xsl:variable name="main-doc" select="/"/>
and where you process the hours change the apply-templates to <xsl:apply-templates select="$hour-array/hour" mode="test-list"/>