根据特定ID和先前属性计算YTD总计

时间:2012-09-19 20:49:40

标签: xml xslt

我正在尝试根据特定ID和YTD计算总计。我到处寻找,似乎无法找到解决方案。 XML doc看起来与此类似:

<pay>
  <pay_year year="Year-2011">
    <paycheck date="Jun-20-2011">
      <hours>
        <hours_type HID="Reg" qty="38.75" pay="1115.25"/> 
      </hours>
    </paycheck>
    <paycheck date="Jul-05-2011">
      <hours>
        <hours_type HID="Reg" qty="76.21" pay="2193.60"/>
        <hours_type HID="Hol" qty="7.75" pay="223.07"/>
      </hours>
    </paycheck>
    <paycheck date="Jul-20-2011">
      <hours>
        <hours_type HID="Reg" qty="76.21" pay="2193.60"/>
        <hours_type HID="Sic" qty="7.75" pay="223.07"/>
      </hours>
    </paycheck>
  </pay_year>
</pay>

我正在使用的XSLT是:

<xsl:template match="hours">
 <xsl:apply-templates select="hours_type">
   <xsl:sort order="descending" />
 </xsl:apply-templates>

<tr>
  <th class="sub" colspan="" align="justify">Subtotal / Totals YTD</th>
  <td class="sub"><xsl:value-of select="sum(hours_type/@qty)" /></td>
  <td class="sub"><xsl:value-of select="format-number(sum(preceding::paycheck/hours/hours_type/@qty) + sum(hours_type/@qty), '###,###.##')"/></td>
  <td class="sub">
    <xsl:value-of select="format-number(sum(hours_type/@pay), '$###,##0.00')" />
  </td>
  <td class="sub">
    <xsl:value-of select="format-number(sum(preceding::paycheck/hours/hours_type/@pay) + sum(hours_type/@pay), '$###,##0.00')"/>
  </td>
</tr>
</xsl:template>

<xsl:template match="hours_type">
<xsl:if test="position()=1">
<xsl:apply_templates select="@qty" />
<!--Not Sure how to make this work here -->
<xsl:apply_templates select="@pay" />
<!--Not Sure how to make this work here -->
</xsl:if>
<xsl:if test="position()=2">
<xsl:apply_templates select="@qty" />
<!--Not Sure how to make this work here -->
<xsl:apply_templates select="@pay" />
<!--Not Sure how to make this work here -->
</xsl:if>
<xsl:if test="position()=3">
<xsl:apply_templates select="@qty" />
<!--Not Sure how to make this work here -->
<xsl:apply_templates select="@pay" />
<!--Not Sure how to make this work here -->
</xsl:if>
</xsl:template>

<xsl:template match="@qty|@pay">
<td align="justify"><xsl:value-of select="." /></td>
</xsl:template>

输出在html中看起来像这样:

Date---------Hours Type-----------Qty-----YTD-------Amount-----Pay YTD
Jun-20-2011--Reg------------------38.75---38.75-----1115.25----1115.25
Subtotal--------------------------38.78---38.75-----1115.25----1115.25

Jul-05-2011--Reg------------------76.21---114.96----2193.60----3308.85
-------------Hol------------------7.75----7.75------223.07-----223.07
Subtotal--------------------------83.96---122.71----2416.67----3531.92

Jul-20-2011--Reg------------------76.21---191.17----2193.60----5502.45
-------------Sic------------------7.75----7.75------223.07-----223.07
Subtotal--------------------------83.96---198.92----2416.67----5725.52

我可以很好地获得Subtotal一行,问题是我无法通过特定ID获得内联YTD总计。我可能会比这更难。

1 个答案:

答案 0 :(得分:0)

首先,对于您的小计,您目前正在执行此操作

<xsl:value-of 
   select="format-number(sum(preceding::paycheck/hours/hours_type/@qty) 
   + sum(hours_type/@qty), '###,###.##')"/>

这有几个问题。首先,您可能应该使用前兄弟,而不是前面的,因为否则如果它们出现在您的XML中,它可能会提前几年。其次,小计仅需要总计以前的值,其中 @HID 属性存在于您正在查看的当前薪水支持/小时中。

因此你需要略显蹩脚的表达

<xsl:value-of 
    select="format-number(sum(../preceding-sibling::paycheck/hours/hours_type
       [@HID=current()/hours_type/@HID]/@qty) 
       + sum(hours_type/@qty), '###,###.##')"/>

同样,对于 hours_type 模板,您可以使用前兄弟进行总计

<xsl:value-of 
   select="@qty + sum(../../preceding-sibling::paycheck/hours/hours_type
     [@HID = current()/@HID]/@qty)" />

尝试以下XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="pay_year">
      <table>
         <tr>
            <th>Date</th>
            <th>Type</th>
            <th>Qty</th>
            <th>Qty YTD</th>
            <th>Pay</th>
            <th>Pay YTD</th>
         </tr>
         <xsl:apply-templates select="paycheck/hours" />
      </table>
   </xsl:template>


   <xsl:template match="hours">
      <xsl:apply-templates select="hours_type">
         <xsl:sort order="descending"/>
      </xsl:apply-templates>

      <tr>
         <th class="sub" colspan="2" align="justify">Subtotal / Totals YTD</th>
         <td class="sub">
            <xsl:value-of select="format-number(sum(hours_type/@qty), '###,##0.00')"/>
         </td>
         <td class="sub">
            <xsl:value-of select="format-number(sum(../preceding-sibling::paycheck/hours/hours_type[@HID=current()/hours_type/@HID]/@qty) + sum(hours_type/@qty), '###,###.##')"/>
         </td>
         <td class="sub">
            <xsl:value-of select="format-number(sum(hours_type/@pay), '###,##0.00')"/>
         </td>
         <td class="sub">
            <xsl:value-of select="format-number(sum(../preceding-sibling::paycheck/hours/hours_type[@HID=current()/hours_type/@HID]/@pay) + sum(hours_type/@pay), '###,##0.00')"/>
         </td>
      </tr>
   </xsl:template>

   <xsl:template match="hours_type">
      <tr>
         <td>
            <xsl:value-of select="../../@date" />
         </td>
         <td>
            <xsl:value-of select="@HID" />
         </td>
         <xsl:apply-templates select="@qty"/><!--Not Sure how to make this work here -->
         <td align="justify">
            <xsl:value-of select="@qty + sum(../../preceding-sibling::paycheck/hours/hours_type[@HID = current()/@HID]/@qty)" />
         </td>
         <xsl:apply-templates select="@pay"/><!--Not Sure how to make this work here -->
         <td align="justify">
            <xsl:value-of select="@pay + sum(../../preceding-sibling::paycheck/hours/hours_type[@HID = current()/@HID]/@pay)" />
         </td>
      </tr>
   </xsl:template>

   <xsl:template match="@qty|@pay">
      <td align="justify">
         <xsl:value-of select="."/>
      </td>
   </xsl:template>
</xsl:stylesheet>

当应用于您的示例XML时,输出以下内容

<table>
   <tr>
      <th>Date</th>
      <th>Type</th>
      <th>Qty</th>
      <th>Qty YTD</th>
      <th>Pay</th>
      <th>Pay YTD</th>
   </tr>
   <tr>
      <td>Jun-20-2011</td>
      <td>Reg</td>
      <td align="justify">38.75</td>
      <td align="justify">38.75</td>
      <td align="justify">1115.25</td>
      <td align="justify">1115.25</td>
   </tr>
   <tr>
      <th class="sub" colspan="2" align="justify">Subtotal / Totals YTD</th>
      <td class="sub">38.75</td>
      <td class="sub">38.75</td>
      <td class="sub">1,115.25</td>
      <td class="sub">1,115.25</td>
   </tr>
   <tr>
      <td>Jul-05-2011</td>
      <td>Reg</td>
      <td align="justify">76.21</td>
      <td align="justify">114.96</td>
      <td align="justify">2193.60</td>
      <td align="justify">3308.85</td>
   </tr>
   <tr>
      <td>Jul-05-2011</td>
      <td>Hol</td>
      <td align="justify">7.75</td>
      <td align="justify">7.75</td>
      <td align="justify">223.07</td>
      <td align="justify">223.07</td>
   </tr>
   <tr>
      <th class="sub" colspan="2" align="justify">Subtotal / Totals YTD</th>
      <td class="sub">83.96</td>
      <td class="sub">122.71</td>
      <td class="sub">2,416.67</td>
      <td class="sub">3,531.92</td>
   </tr>
   <tr>
      <td>Jul-20-2011</td>
      <td>Reg</td>
      <td align="justify">76.21</td>
      <td align="justify">191.17</td>
      <td align="justify">2193.60</td>
      <td align="justify">5502.45</td>
   </tr>
   <tr>
      <td>Jul-20-2011</td>
      <td>Sic</td>
      <td align="justify">7.75</td>
      <td align="justify">7.75</td>
      <td align="justify">223.07</td>
      <td align="justify">223.07</td>
   </tr>
   <tr>
      <th class="sub" colspan="2" align="justify">Subtotal / Totals YTD</th>
      <td class="sub">83.96</td>
      <td class="sub">198.92</td>
      <td class="sub">2,416.67</td>
      <td class="sub">5,725.52</td>
   </tr>
</table>