xml – XSLT:多次添加数字和打印小计

我是XSLT的初学者,并且发现我不能只是将数字加到变量中并以任何方式改变它的值.

我有一个XML文档,其中包含我需要添加的数字列表,直到元素与特定属性值匹配,然后打印该数字将其重置为0并继续累加其余部分,直到我再次看到该特定属性.

例如,我有这个XML:

<list>
 <entry>
  <field type="num" value="189.5" />
 </entry>
 <entry>
  <field type="num" value="1.5" />
 </entry>
 <entry>
  <field type="summary" />
 </entry>
 <entry>
  <field type="num" value="9.5" />
 </entry>
 <entry>
  <field type="num" value="11" />
 </entry>
 <entry>
  <field type="num" value="10" />
 </entry>
 <entry>
  <field type="summary" />
 </entry>
</list>

现在我希望我的XSLT打印出来:

189.5
1.5
#191#
9.5
11
10
#30.5#

我已经读过,我可以通过使用sum()和条件来做到这一点.我知道如何使用for-each并相对指向元素,iam也可以通过简单地总结所有类型= num来使用sum(),但是如何仅将第一个数字加起来直到type = summary出现,然后仅下一个sum从最后一个类型=摘要到下一个

我希望这样的事情:

<xsl:for-each select="list/entry">
 <xsl:if test="field[@type='summary']">
  <!-- we are Now at a type=summary element,Now sum up -->
  #<xsl:value-of select="sum(WHAT_TO_PUT_HERE?)" />#
 </xsl:if>
 <xsl:if test="field[@type='num']">
  <xsl:value-of select="field/@value" />
 </xsl:if>
</xsl:for-each>

感谢任何帮助.

正如作为注释建议的分组的不同解决方案一样 – 您也可以使用匹配模式来获取总和:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="field[@type='num']">
  <xsl:value-of select="@value"/>
<xsl:text>&#x0A;</xsl:text>
  </xsl:template>
  <xsl:template match="entry[field[@type='summary']]">
  <xsl:variable name="sumCount" select="count(preceding-sibling::entry[field[@type='summary']])"/>
     <xsl:text>#</xsl:text>
     <xsl:value-of select="sum(preceding-sibling::entry[count(preceding-sibling::entry[field[@type='summary']]) = $sumCount]/field[@type='num']/@value)"/>
    <xsl:text>#&#x0A;</xsl:text>     
  </xsl:template>
</xsl:transform>

应用于输入XML时,会生成输出

189.5
1.5
#191#
9.5
11
10
#30.5#

模板匹配字段[@type =’num’]打印该值并添加换行符,模板匹配条目[field [@ type =’summary’]]使用该变量

<xsl:variable name="sumCount" select="count(preceding-sibling::entry[field[@type='summary']])"/>

检查类型摘要发生的前几个字段的数量.然后,仅打印具有相同数量的在前摘要字段的num类型的条目的所有值的总和:

<xsl:value-of select="sum(preceding-sibling::entry[
                      count(preceding-sibling::entry[field[@type='summary']]) = $sumCount
                      ]/field[@type='num']/@value)"/>

更新:要更详细地解释它是如何按要求工作的:在模板匹配条目[field [@ type =’summary’]]中,变量sumCount计算所有以前具有类型摘要字段的条目:

count(preceding-sibling::entry[field[@type='summary']])

因此,当模板与第一个汇总字段匹配时,sumCount的值为0,当匹配第二个汇总字段时,sumCount为1.
第二行使用sum函数

sum(
    preceding-sibling::entry
     [
      count(preceding-sibling::entry[field[@type='summary']]) = 
      $sumCount
     ]
     /field[@type='num']/@value
   )

对所有先前(前面)条目的所有字段[@type =’num’] / @值求和,该条目具有与当前类型摘要字段相同的先前字段类型摘要

count(preceding-sibling::entry[field[@type='summary']]) = $sumCount

因此,当匹配第二个摘要时,将仅汇总值为9.5,10和11的num字段的值,因为它们具有与当前摘要字段相同的先前汇总字段数量.
对于值为189.5和1.5的num字段,

count(preceding-sibling::entry[field[@type='summary']])

为0,因此sum函数中省略了这些字段.

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念