首页 > 解决方案 > XSL 如何使用 sum 到 foreach 中执行赔率程序?

问题描述

我有个问题。如何对 a 的结果进行汇总<xsl:for-each>?结果只能出现一次。这在我看来是:“0.1,0.3”,但我想要这些值的总和。

我试图将所有内容放在一个变量中,但我没有得到任何东西,我想它不允许我将变量放入其他变量中。那么,我能做些什么呢?

XML

<datos>
    <arbol nbarbol="Tiendas" n="100">
        <atributo nbatributo="Tiendas">
            <valor nbvalor="TiendaA" f="70">
                <atributo>
                    <valor nbvalor="ProductoA" f="10" encendido="1"></valor>
                    <valor nbvalor="ProductoB" f="20" encendido="0"></valor>
                    <valor nbvalor="ProductoC" f="30" encendido="1"></valor>
                </atributo>
            </valor>
        </atributo>
    </arbol>
</datos>

XSLT

<xsl:stylesheet version="1.0" xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <xsl:for-each select="descendant::valor">
            <xsl:variable name="instancias">
                <xsl:value-of select="@encendido" />
            </xsl:variable>
            <xsl:if test="$instancias='1'">
                <xsl:variable name="probadatos">
                    <xsl:value-of select="@f div ../../@f" />
                </xsl:variable>
                <xsl:value-of select="($probadatos) * (../../@f div ../../../../@n)" />
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

标签: xmlxslt

解决方案


XSLT 1.0由于 XSLT 1.0 不允许在sum()函数中使用 XPath,因此使用计算值求和有点麻烦。如果您有升级到处理器的自由,那么使用该函数XSLT 2.0执行计算的求和会容易得多。sum()

但是,如果您没有选项并且必须使用XSLT 1.0,那么您将必须使用递归模板调用来执行计算,然后继续添加所有计算以生成最终总和。

下面是可以提供帮助的 XSLT。

<xsl:stylesheet version="1.0" xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="xalan">
    <xsl:output method="xml" />
    <xsl:strip-space elements="*" />

    <xsl:template match="arbol">
        <xsl:variable name="n" select="@n" />
        <xsl:variable name="f" select="atributo/valor/@f" />
        <xsl:for-each select="atributo/valor/atributo">
            <summation>
                <xsl:call-template name="ProductSum">
                    <xsl:with-param name="nodeSet" select="*" />
                    <xsl:with-param name="n" select="$n" />
                    <xsl:with-param name="f" select="$f" />
                </xsl:call-template>
            </summation>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="ProductSum">
        <xsl:param name="nodeSet" />
        <xsl:param name="n" />
        <xsl:param name="f" />
        <xsl:param name="sum" select="0" />

        <xsl:variable name="nodeStart" select="$nodeSet[1]" />
        <xsl:variable name="nodeEnd" select="$nodeSet[position() > 1]" />

        <!-- Perform computation for the current node -->
        <xsl:variable name="currSum">
            <xsl:choose>
                <xsl:when test="$nodeStart/@encendido = '1'">
                    <xsl:value-of select="format-number(($nodeStart/@f div $f) * ($f div $n), '#0.0')" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="0" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <!-- Check whether the current node is not the last node in the node-set  -->
        <xsl:choose>
            <xsl:when test="not($nodeEnd)">
                <xsl:value-of select="$sum + $currSum" />
            </xsl:when>
            <xsl:otherwise>
                <!-- Recursive call to the same template -->
                <xsl:call-template name="ProductSum">
                    <xsl:with-param name="nodeSet" select="$nodeEnd" />
                    <xsl:with-param name="n" select="$n" />
                    <xsl:with-param name="f" select="$f" />
                    <xsl:with-param name="sum" select="$sum + $currSum" />
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

输出

<summation>0.4</summation>

这是一个类似的问题,该解决方案显示了使用XSLT 2.0XSLT 1.0 Extension Functions生成总和的附加选项。

在 XSLT 中使用 foreach 添加属性值


推荐阅读