对XSLT1.0中节点集的元素求和

对XSLT1.0中节点集的元素求和,xslt,Xslt,我有以下xml,其结构相同,但节点和值可能不同: <?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="test.xsl"?> <main> <_All> <_001372> <_2012-Oct-10> <Employe

我有以下xml,其结构相同,但节点和值可能不同:

    <?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<main>
    <_All>
        <_001372>
            <_2012-Oct-10>
                <Employee_Amount>1.0</Employee_Amount>
                <Combo_Savings_Amount>2.0</Combo_Savings_Amount>
                <Total_Sales>3.0</Total_Sales>
                <Dine_in_Amount>4.0</Dine_in_Amount>
                <Promos_Actual>5.0</Promos_Actual>
                <Cash_Count>6.0</Cash_Count>
                </_2012-Oct-10>
            <_2012-Oct-11>
                <Employee_Amount>7.0</Employee_Amount>
                <Combo_Savings_Amount>0.0</Combo_Savings_Amount>
                <Total_Sales>0.0</Total_Sales>
                <Dine_in_Amount>0.0</Dine_in_Amount>
                <Promos_Actual>0.0</Promos_Actual>
                <Cash_Count>0.0</Cash_Count>
                </_2012-Oct-11>
            </_001372>
        <_024139>
            <_2012-Oct-10>
                <Employee_Amount>0.0</Employee_Amount>
                <Combo_Savings_Amount>313.148999999997</Combo_Savings_Amount>
                <Total_Sales>3515.5</Total_Sales>
                <Dine_in_Amount>543.86</Dine_in_Amount>
                <Promos_Actual>0.0</Promos_Actual>
                <Cash_Count>330.0</Cash_Count>
                </_2012-Oct-10>
            <_2012-Oct-11>
                <Employee_Amount>10.0</Employee_Amount>
                <Combo_Savings_Amount>17.0</Combo_Savings_Amount>
                <Total_Sales>5.0</Total_Sales>
                <Dine_in_Amount>7.0</Dine_in_Amount>
                <Promos_Actual>0.0</Promos_Actual>
                <Cash_Count>20.0</Cash_Count>
                </_2012-Oct-11>
            </_024139>
        <_101010>
            <_2012-Oct-10>
                <Employee_Amount>5.0</Employee_Amount>
                <Combo_Savings_Amount>0.0</Combo_Savings_Amount>
                <Total_Sales>0.0</Total_Sales>
                <Dine_in_Amount>0.0</Dine_in_Amount>
                <Promos_Actual>0.0</Promos_Actual>
                <Cash_Count>0.0</Cash_Count>
                </_2012-Oct-10>
            <_2012-Oct-11>
                <Employee_Amount>0.0</Employee_Amount>
                <Combo_Savings_Amount>0.0</Combo_Savings_Amount>
                <Total_Sales>0.0</Total_Sales>
                <Dine_in_Amount>0.0</Dine_in_Amount>
                <Promos_Actual>0.0</Promos_Actual>
                <Cash_Count>0.0</Cash_Count>
                </_2012-Oct-11>
            </_101010>
    </_All>
</main>

1
2
3
4
5
6
7
0
0
0
0
0
0
313.148999999997
3515.5
543.86
0
330
10
17
5
7
0
20
5
0
0
0
0
0
0
0
0
0
0
0
我需要对商店的所有元素求和。例如,我需要对日期date01和date02的员工金额求和。与所有节点相同。我的尝试如下:

<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="html" indent="yes" />
    <xsl:template match="/*">
        <table border="1" cellspacing="1" cellpadding="1"
            align="center">
            <tr bgcolor="#8181F7">
                <xsl:apply-templates select="/*/*/*/*" mode="ColHeader" />
            </tr>
            <tr bgcolor="#00FFFF">
                <td>
                    <xsl:value-of
                        select="translate(name(child::*),'_',' ')" />
                </td>
                <td>&#160;</td>
                <xsl:for-each select="/*[1]/*[1]/*[1]/*[1]/*">
                    <xsl:variable name="pos" select="position()" />
                    <td>
                        <xsl:value-of
                            select='format-number(sum(/*/*/*/*/*[$pos]),"#.##")' />
                    </td>
                </xsl:for-each>
            </tr>
            <xsl:apply-templates select="/*/*/*" mode="values" />
        </table>
    </xsl:template>

    <xsl:template match="/*/*/*/*" mode="ColHeader">
        <xsl:if test="position() = 1">
            <th>Region</th>
            <th>Store</th>
            <xsl:for-each select="./*">
                <th>
                    <xsl:value-of select="translate(name(),'_',' ')" />
                </th>
            </xsl:for-each>
        </xsl:if>
    </xsl:template>
    <xsl:template match="/*/*/*" mode="values">
        <xsl:for-each select=".">
            <tr>
                <td>&#160;</td>
                <td>
                    <xsl:value-of select="translate(name(),'_',' ')" />
                </td>
                <xsl:apply-templates select="./*/*" mode="rollupVal"/>
            </tr>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="/*/*/*/*/*" mode="rollupVal">
        <xsl:variable name="pos1" select="current()"/>
                    <td>
                        <xsl:value-of select='format-number(sum(./node()[$pos1]), "#.##")'/>
                    </td>
    </xsl:template>
</xsl:stylesheet>

 
区域
商场
 
但我无法将这些行相加。请帮帮我。谢谢

已编辑:输出HTML为:

<table align="center" cellpadding="1" cellspacing="1" border="1">
    <tr bgcolor="#8181F7">
    <th>Region</th><th>Store</th><th>Employee Amount</th><th>Combo Savings Amount</th><th>Total Sales</th><th>Dine in Amount</th><th>Promos Actual</th><th>Cash Count</th>
    </tr>
    <tr bgcolor="#00FFFF">
        <td> All</td>
        <td>&nbsp;</td>
        <td>18</td>
        <td>332.15</td>
        <td>3523.5</td>
        <td>554.86</td>
        <td>5</td>
        <td>356</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td> 001372 44CLOSED</td>
        <td>8</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
    </tr>
    <tr>
        <td>&nbsp;</td>
        <td> 024139</td>
        <td>10</td>
        <td>330.15</td>
        <td>3520.5</td>
        <td>550.86</td>
        <td>0</td>
        <td>350</td>
    </tr>
</table>

RegionStoreEmployee AmountCombo储蓄金额SalesDine in AmountPromotos实际现金数
全部的
18
332.15
3523.5
554.86
5.
356
00137442关闭
8.
2.
3.
4.
5.
6.
024139
10
330.15
3520.5
550.86
0
350

这个XSL仍然有点混乱,但它似乎产生了预期的输出:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
  <xsl:output method="html" indent="yes" />
  <xsl:key name="field" match="/*/*/*/*/*" use="local-name()" />
  <xsl:variable name="fieldGroups" select="/*/*/*/*/*[generate-id() = generate-id(key('field', local-name())[1])]" />

  <xsl:template match="/*">
    <table border="1" cellspacing="1" cellpadding="1"
        align="center">
      <tr bgcolor="#8181F7">
        <!-- First date node -->
        <xsl:call-template name="ColHeaders" />
      </tr>
      <!-- All node -->
      <xsl:apply-templates select="*" mode="GrandTotal" />
      <!-- Each store -->
      <xsl:apply-templates select="*/*" mode="values" />
    </table>
  </xsl:template>

  <xsl:template name="EmptyCell">
    <td>&#160;</td>
  </xsl:template>

  <xsl:template match="/*/*" mode="GrandTotal">
    <tr bgcolor="#00FFFF">
      <td>
        <xsl:value-of select="translate(name(.),'_',' ')" />
      </td>
      <xsl:call-template name="EmptyCell" />
      <!-- Each field of first date -->
      <xsl:apply-templates select="$fieldGroups" mode="FieldTotal" />
    </tr>
  </xsl:template>

  <xsl:template match='/*/*/*/*/*' mode='FieldTotal'>
    <xsl:variable name="pos" select="position()" />
    <td>
      <xsl:value-of select='format-number(sum(key("field", local-name())),"0.##")' />
    </td>
  </xsl:template>

  <xsl:template name="ColHeaders">
    <th>Region</th>
    <th>Store</th>
    <xsl:apply-templates select="$fieldGroups" mode="ColHeader" />
  </xsl:template>

  <xsl:template match="*" mode="ColHeader">
    <th>
      <xsl:value-of select="translate(name(),'_',' ')" />
    </th>
  </xsl:template>

  <!-- Matches stores -->
  <xsl:template match="/*/*/*" mode="values">
    <tr>
      <xsl:call-template name="EmptyCell" />
      <td>
        <!-- Store code -->
        <xsl:value-of select="translate(name(),'_',' ')" />
      </td>
      <!-- All fields in first date -->
      <xsl:apply-templates select="*[1]/*" mode="rollupVal"/>
    </tr>
  </xsl:template>

  <xsl:template match="/*/*/*/*/*" mode="rollupVal">
    <xsl:variable name="pos1" select="position()"/>
    <td>
      <xsl:value-of select='format-number(sum(../../*/*[$pos1]), "0.##")'/>
    </td>
  </xsl:template>
</xsl:stylesheet>

 
区域
商场
输出:

<table border="1" cellspacing="1" cellpadding="1" align="center">
  <tr bgcolor="#8181F7">
    <th>Region</th>
    <th>Store</th>
    <th>Employee Amount</th>
    <th>Combo Savings Amount</th>
    <th>Total Sales</th>
    <th>Dine in Amount</th>
    <th>Promos Actual</th>
    <th>Cash Count</th>
  </tr>
  <tr bgcolor="#00FFFF">
    <td> All</td>
    <td> </td>
    <td>18</td>
    <td>332.14</td>
    <td>3523.5</td>
    <td>554.86</td>
    <td>5</td>
    <td>356</td>
  </tr>
  <tr>
    <td> </td>
    <td> store01</td>
    <td>8</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
  <tr>
    <td> </td>
    <td> store02</td>
    <td>10</td>
    <td>330.14</td>
    <td>3520.5</td>
    <td>550.86</td>
    <td>0</td>
    <td>350</td>
  </tr>
</table>

区域
商场
员工人数
组合储蓄额
总销售额
多吃
实际促销
现金盘点
全部的
 
18
332.14
3523.5
554.86
5.
356
 
store01
8.
2.
3.
4.
5.
6.
 
store02
10
330.14
3520.5
550.86
0
350

预期的输出是什么?我需要将商店中所有日期的元素(如雇员金额)相加。例如,对于date 01的Employee_金额,这应该是8(1+7),对于date 02,这对于特定日期的所有节点都应该是10,依此类推。请在您的问题中添加所需输出HTML的示例。嗨,JLRishe,我已经用所需输出HTML更新了我的问题。谢谢。我在下面添加了一个答案。我不知道你从哪里得到了00137442关闭值和024139值。这些似乎不在源XML中的任何地方。嗨,JLRishe,sum很好,但是当使用我的xsl应用模板时,它会产生一些额外的td,值为0。我将xsl应用于您提供的XML,结果如上图所示。您是指来自不同输入XML的结果吗?我已经用原始XML更新了源XML。这个XML是由DB生成的,所以它的节点可以改变,但它的结构保持不变。因此,我不能使用您在答案中使用的任何内容。这很好,但是对于两个值行,输出包含额外的td,其值为0。谢谢,请尝试更新的XSLT。我已经在你的新XML上验证过了。嗨,JLRishe,你能给我推荐一本学习XSLT1.0的书吗。我是新手。