我只需要一些关于XSL基本功能的帮助。 我想显示先前计算的金额总和。但我不知道该怎么做。 有关信息,XSL必须使用XSLT 1.0,我的技术限制。
例如,这是我的xml。
<A>
<amount>10</amount>
<rate>4</rate>
</A>
<A>
<amount>-21</amount>
<rate>2</rate>
</A>
<B>
<amount>8</amount>
<rate>1</rate>
</B>
<C>
<amount>7</amount>
<rate>32</rate>
</C>
我希望在Total元素中显示每个金额乘以每个相关汇率的总和。
<Total value="230">
<PositiveTotal>
272
</PositiveTotal>
<NegativeTotal>
-42
</NegativeTotal>
</Total>
我不知道该怎么做。
提前致谢
此致
答案 0 :(得分:1)
可能的多种解决方案之一。 它会给你一个想法,如何解决这个。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:variable name="positiveTotal">
<xsl:call-template name="sum">
<xsl:with-param name="items" select="*[not(starts-with(amount,'-') or starts-with(rate, '-'))]"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="negativTotal">
<xsl:call-template name="sum">
<xsl:with-param name="items" select="*[starts-with(amount,'-') or starts-with(rate, '-')]"/>
</xsl:call-template>
</xsl:variable>
<Total value="{$positiveTotal + $negativTotal}">
<PositivTotal>
<xsl:value-of select="format-number($positiveTotal, '0')"/>
</PositivTotal>
<NegativeTotal>
<xsl:value-of select="format-number($negativTotal, '0')"/>
</NegativeTotal>
</Total>
</xsl:template>
<xsl:template name="sum">
<xsl:param name="items" />
<xsl:param name="total" select="0" />
<xsl:choose>
<xsl:when test="not($items)">
<xsl:value-of select="$total"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="sum">
<xsl:with-param name="items" select="$items[position() > 1]" />
<xsl:with-param name="total"
select="$total + ($items[1]/amount * $items[1]/rate)" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
!! 将match="root"
更改为您的根节点!鉴于source-xml无效。
已经有很多sum
- 问题!请参阅屏幕右侧的相关框。
答案 1 :(得分:0)
这个问题已被多次询问,并且在SO上进行类似搜索的链接应该会给你很多想法。
在XSLT 2.0中计算计算值的总和是微不足道的,但在XSLT 1.0中它并不容易,因为它的数据模型中没有这样的数据类型作为一组数字(仅限sum())适用于一组节点)。可能的解决方案包括:
(a)递归模板调用,它将运行总计作为参数提供给模板,添加下一个值,然后再次调用模板以使用新的运行总计处理列表的其余部分
(b)多相变换,其中计算值在一个阶段中放置在XML节点中,并在第二阶段使用sum()函数求和
(c)使用FXSL库,该库使用xsl:apply-templates来模拟高阶函数,然后提供折叠机制,可以专门用于实现求和。
(d)用过程式编程语言调用扩展函数
(e)升级到XSLT 2.0。
答案 2 :(得分:0)
我建议你这样做:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<!-- first pass -->
<xsl:variable name="summands-rtf">
<xsl:for-each select="*">
<value>
<xsl:value-of select="amount * rate" />
</value>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="summands" select="exsl:node-set($summands-rtf)/value" />
<!-- output -->
<Total value="{sum($summands)}">
<PositiveTotal>
<xsl:value-of select="sum($summands[. > 0])" />
</PositiveTotal>
<NegativeTotal>
<xsl:value-of select="sum($summands[. < 0])" />
</NegativeTotal>
</Total>
</xsl:template>
</xsl:stylesheet>
当应用于格式正确的 XML输入(具有单个根元素)时:
<强> XML 强>
<root>
<A>
<amount>10</amount>
<rate>4</rate>
</A>
<A>
<amount>-21</amount>
<rate>2</rate>
</A>
<B>
<amount>8</amount>
<rate>1</rate>
</B>
<C>
<amount>7</amount>
<rate>32</rate>
</C>
</root>
结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<Total value="230">
<PositiveTotal>272</PositiveTotal>
<NegativeTotal>-42</NegativeTotal>
</Total>