XSLT 循环嵌套数据

问题描述 投票:0回答:1

我有嵌套的 xml 数据。我正在循环项目元素,并希望使用递归获得所有项目的价格总和。

<?xml version="1.0" encoding="utf-8"?>
<order>
  <item>
    <name>Product A</name>
    <price>10.00</price>
    <item>
      <name>Product B</name>
      <price>5.00</price>
      <item>
        <name>Sub-Product 1</name>
        <price>2.00</price>
      </item>
    </item>
  </item>
  <item>
    <name>Product 2</name>
    <price>2.00</price>
  </item>
</order>

我看到循环时不考虑最后一个项目元素。我不确定我错过了什么。

`<!-- Recursive template to calculate the sum of prices -->
  <xsl:template name="sumPrices">
    <xsl:param name="items"/>
    <xsl:param name="sum"/>

    <!-- Iterate over each item -->
    <xsl:for-each select="$items">
      <!-- Add the price of the current item to the sum -->
      <xsl:variable name="currentPrice" select="number($items/price)"/>
      <xsl:variable name="newSum" select="$sum + $currentPrice"/>
      <!-- Recursive call for sub-items -->
      <xsl:call-template name="sumPrices">
        <xsl:with-param name="items" select="item"/>
        <xsl:with-param name="sum" select="$newSum"/>
      </xsl:call-template>
    </xsl:for-each>

    <!-- Output the total sum -->
    <xsl:if test="not($items)">
      <total>
        <xsl:value-of select="$sum"/>
      </total>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
xml recursion xslt nested
1个回答
0
投票

我不确定我错过了什么。

当您没有向我们展示模板的初始调用时,很难说您错过了什么,因此我们无法重现您的问题。

无论如何,都不需要递归。您可以简单地使用:

<xsl:value-of select="sum(//item/price)"/> 

返回所有商品价格的总和,无论它们在输入 XML 层次结构中的位置如何。


如果出于某种原因,您想使用递归,那么可以这样做:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <total>
        <xsl:call-template name="sumPrices">
            <xsl:with-param name="items" select="//item"/>
        </xsl:call-template>
    </total>
</xsl:template>

<xsl:template name="sumPrices">
    <xsl:param name="items"/>
    <xsl:param name="sum" select="0"/>
    <xsl:choose>
        <xsl:when test="$items">
            <xsl:variable name="currentPrice" select="$items[1]/price"/>
            <!-- recursive call -->
            <xsl:call-template name="sumPrices">
                <xsl:with-param name="items" select="$items[position() > 1]"/>
                <xsl:with-param name="sum" select="$sum + $currentPrice"/>
              </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$sum"/>
        </xsl:otherwise>
    </xsl:choose>    
</xsl:template>

</xsl:stylesheet>

但是,没有理由这样做。

© www.soinside.com 2019 - 2024. All rights reserved.