템플릿 내에서 XSLT 키를 사용할 수 없음 (노트 세트 배열 사용)

Nov 14 2020

저는 하루 중 각 시간에 대한 값 배열로 XLT 문서를 만들었습니다. 노드 세트를 사용하여 변수를 생성하여이 배열을 반복합니다.

라는 각 시간에 대한 총 개수를 보유하는 키를 생성했습니다 key-hours. 그러나 $hour-array변수 의 값을 전달 하면 해당 총 개수가 표시되지 않습니다.

XML 데이터

    <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 &gt; 50">
                  <xsl:attribute name="class">red-90</xsl:attribute>
               </xsl:when>
               <xsl:when test="$pct &gt; 40"> <xsl:attribute name="class">red-70</xsl:attribute> </xsl:when> <xsl:when test="$pct &gt; 30">
                  <xsl:attribute name="class">red-50</xsl:attribute>
               </xsl:when>
               <xsl:when test="$pct &gt; 20"> <xsl:attribute name="class">red-30</xsl:attribute> </xsl:when> <xsl:when test="$pct &gt; 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>

이로 인해 합계 열이 실제 합계 합계로 채워지지 않습니다. 다음은 그 모습입니다.

여기에 당신이 놀 수있는 결과의 바이올린이 있습니다. https://xsltfiddle.liberty-development.net/pNvtBGk

답변

1 MartinHonnen Nov 14 2020 at 04:19

다음을 수행하여 컨텍스트를 변경하는 것이 좋습니다.

   <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 &gt; 50"> <xsl:attribute name="class">red-90</xsl:attribute> </xsl:when> <xsl:when test="$pct &gt; 40">
                 <xsl:attribute name="class">red-70</xsl:attribute>
              </xsl:when>
              <xsl:when test="$pct &gt; 30"> <xsl:attribute name="class">red-50</xsl:attribute> </xsl:when> <xsl:when test="$pct &gt; 20">
                 <xsl:attribute name="class">red-30</xsl:attribute>
              </xsl:when>
              <xsl:when test="$pct &gt; 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:variable name="main-doc" select="/"/>및 시간을 처리하는 곳에서 적용 템플릿을<xsl:apply-templates select="$hour-array/hour" mode="test-list"/>

https://xsltfiddle.liberty-development.net/pNvtBGk/2