加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 07:59:46 所属栏目:百科 来源:网络整理
导读:我是XSLT的初学者,并且发现我不能只是将数字加到变量中并以任何方式改变它的值. 我有一个XML文档,其中包含我需要添加的数字列表,直到元素与特定属性值匹配,然后打印该数字将其重置为0并继续累加其余部分,直到我再次看到该特定属性. 例如,我有这个XML: list
我是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函数中省略了这些字段.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读