【问题标题】:sum of previous nodes as value of current node in XSLT先前节点的总和作为 XSLT 中当前节点的值
【发布时间】:2016-03-29 16:53:42
【问题描述】:

我正在尝试获取目标 xml,使得节点的值是以前相似节点值之和的逗号分隔值。例如:

输入:

<Items>
  <Item>
    <name>Drakshi</name>
    <price>50</price>
  </Item>
  <Item>
    <name>Godambi</name>
    <price>30</price>
  </Item>
  <Item>
    <name>Badami</name>
    <price>70</price>
  </Item>
</Items>

输出:

<result>
 50,80,150
</result>

正如你在上面看到的那样,它是 50, (50+30), (50+30+70)

我尝试了 for-each Item 并且能够找到仅当前节点和前一个选定节点的总和。你能在这里指导我吗

【问题讨论】:

    标签: html xml xslt stylesheet xslt-2.0


    【解决方案1】:

    试试这样的:

    <xsl:template match="Items">
      <result>
        <xsl:for-each select="Item">
          <xsl:value-of select="sum(preceding-sibling::Item/price | price) " />
          <xsl:if test="position() != last()">, </xsl:if>
        </xsl:for-each>
      </result>
     </xsl:template>
    

    【讨论】:

      【解决方案2】:

      虽然您可以使用sum(preceding-sibling::...),但更有效的解决方案是使用递归模板一次累加一个值:

      <xsl:template match="/Items">
          <result>
              <xsl:call-template name="run-total">
                  <xsl:with-param name="values" select="Item/price"/>
              </xsl:call-template>
          </result>
      </xsl:template>
      
      <xsl:template name="run-total">
          <xsl:param name="values"/> 
          <xsl:param name="i" select="1"/> 
          <xsl:param name="total" select="0"/> 
          <xsl:variable name="balance" select="$total + $values[$i]" />
          <xsl:value-of select="$balance" />
          <xsl:if test="$i &lt; count($values)">
              <xsl:text>,</xsl:text>
              <xsl:call-template name="run-total">
                  <xsl:with-param name="values" select="$values"/>
                  <xsl:with-param name="i" select="$i + 1"/>
                  <xsl:with-param name="total" select="$balance"/>
              </xsl:call-template>
          </xsl:if>
      </xsl:template>
      

      【讨论】:

        【解决方案3】:

        如果你想用 XSLT 2.0 解决它,那么我认为你不需要任何用户定义的函数,你可以编写一个 XPath 2.0 表达式:

        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            exclude-result-prefixes="xs"
            version="2.0">
        
        <xsl:template match="Items">
            <result>
                <xsl:value-of 
                    select="for $pos in 1 to count(Item)
                            return sum(subsequence(Item, 1, $pos)/price)"
                    separator=","/>
            </result>
        </xsl:template>
        
        </xsl:stylesheet>
        

        【讨论】:

          【解决方案4】:

          感谢您的回复。我遵循了这种对我有用的方法:

          <xsl:function name="kk:getSumTillIndex">
              <xsl:param name="index"/>     
              <xsl:variable name="Var_PriceArray" select="$Items/item[position()&lt;=$index]//price/text()"/>
              <xsl:for-each select="$Var_PriceArray">
                  <Item>
                      <xsl:value-of select="current()"/>
                  </Item>
              </xsl:for-each>
          </xsl:function>
          
          
          <xsl:function name="kk:calulatePriceSequence">
              <xsl:variable name="set" select="$Items/Item" />
              <xsl:variable name="count" select="count($set)" />
          
              <xsl:for-each select="$set">
                   <xsl:if test="position() &lt;= $count">
                   <xsl:value-of select="sum(kk:getSumTillIndex(position()))"/>
          
                      <xsl:if test="position() &lt; number($count)-1">
                          <xsl:value-of select="','" />
                      </xsl:if>   
                  </xsl:if>
                  </xsl:for-each>
          </xsl:function> 
          

          【讨论】:

            猜你喜欢
            • 2010-11-04
            • 2013-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-07
            • 2011-03-13
            • 1970-01-01
            • 2013-12-28
            相关资源
            最近更新 更多