使用XSL保持运行总计

时间:2010-06-18 16:44:28

标签: xml xslt

我有以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="disp.xsl"?>
<root>
 <node type="a"> 
  <value>4</value>
 </node>
 <node type="b">
  <value>2</value>
 </node>
 <node type="a">
  <value>3</value>
 </node>
 <node type="b">
  <value>1</value>
 </node>
</root

我想生成一个报告,该报告总计每种类型的值元素并保持运行总计。我想,我想:

type: a total:7 cumulative total:7
type: b total:3 cumulative total:10

这是我的XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="eachtype" match="node" use="@type" />
<xsl:template match="/root">
  <html>
  <body>
   <xsl:for-each select="node">
    Value: <xsl:value-of select="value"/> (Cumulative value: <xsl:variable name="temp" select="sum(preceding-sibling::node/value)+value"/><xsl:value-of select="$temp"/>)<br />
   </xsl:for-each>
   <hr />
   <xsl:for-each select="node">
    <xsl:variable name="thisType" select="@type"/>
    type: <xsl:value-of select="$thisType" /> Value: <xsl:value-of select="value"/> (Cumulative value: <xsl:variable name="temp2" select="sum(preceding-sibling::node/value)+value"/><xsl:value-of select="$temp2"/>)<br />
   </xsl:for-each>
   <hr />
      <xsl:for-each select="node[generate-id(.)=generate-id(key('eachtype',@type)[1])]">
    <xsl:variable name="thisType" select="@type"/>
    type: <xsl:value-of select="$thisType" /> Total: <xsl:value-of select="sum(/root/node[@type=$thisType]/value)"/> (Cumulative value: <xsl:variable name="temp2" select="sum(preceding-sibling::value)+value"/><xsl:value-of select="$temp2"/>)<br />
   </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

产生以下输出:

Value: 4 (Cumulative value: 4)
Value: 3 (Cumulative value: 7)
Value: 2 (Cumulative value: 9)
Value: 1 (Cumulative value: 10)

--------------------------------------------------------------------------------
type: a Value: 4 (Cumulative value: 4)
type: a Value: 3 (Cumulative value: 7)
type: b Value: 2 (Cumulative value: 9)
type: b Value: 1 (Cumulative value: 10)

--------------------------------------------------------------------------------
type: a Total: 7 (Cumulative value: 4)
type: b Total: 3 (Cumulative value: 2)

我找不到在最后两行中获得累计总值的正确值的方法。是否有任何XSL资深人士可以帮助我尝试使用XSL?

1 个答案:

答案 0 :(得分:3)

此转化

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

 <xsl:key name="kType" match="@type" use="."/>

 <xsl:template match="/">
  <xsl:for-each select=
   "*/*/@type
          [generate-id()
          =
           generate-id(key('kType', .)[1])
           ]">
    <xsl:value-of  select=
     "concat('type: ', .,
             ' total: ', sum(/*/*[@type = current()]/value),

             ' cumulative total: ',
             /*/*[@type = current()][last()]/value
            +
             sum(/*/*[@type = current()][last()]/preceding-sibling::*/value),

             '&#xA;'
              )
     "/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<root>
    <node type="a">
        <value>4</value>
    </node>
    <node type="a">
        <value>3</value>
    </node>
    <node type="b">
        <value>2</value>
    </node>
    <node type="b">
        <value>1</value>
    </node>
</root>

生成想要的正确结果

type: a total: 7 cumulative total: 7
type: b total: 3 cumulative total: 10

请注意此解决方案效率不高。刹车后我会提供一个更有效(递归)的。 :)