使用XSLT 1.0/2.0实现XML数值求和并移除末尾零的求助
解决方案:XML数值求和并移除末尾零
没问题,我来帮你搞定这个需求——既要对XML中所有linesTotal节点的数值求和,又要把结果末尾的零去掉(比如2030变成203)。下面分别提供XSLT 1.0和XSLT 2.0的实现方案:
XSLT 2.0 方案
XSLT 2.0支持更强大的字符串处理能力,实现起来更简洁直观:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <!-- 1. 计算所有linesTotal节点的数值总和 --> <xsl:variable name="total" select="sum(//linesTotal)"/> <!-- 2. 用正则表达式移除末尾所有连续的零 --> <xsl:value-of select="if ($total = 0) then '0' else replace($total, '0+$', '')"/> </xsl:template> </xsl:stylesheet>
说明:
sum(//linesTotal):直接遍历XML中所有linesTotal节点,快速计算出数值总和(你的例子中会得到2030)。replace($total, '0+$', ''):通过正则表达式匹配结果末尾的所有连续零,将其替换为空字符串,最终得到203。- 额外增加了对总和为0的判断,避免出现空输出的情况(如果所有
linesTotal都是0,会直接输出0)。
XSLT 1.0 方案
XSLT 1.0没有原生的正则替换函数,我们可以通过递归模板来实现移除末尾零的逻辑:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <!-- 1. 先计算所有linesTotal的总和 --> <xsl:variable name="total" select="sum(//linesTotal)"/> <!-- 2. 调用递归模板处理末尾零 --> <xsl:call-template name="strip-trailing-zeros"> <xsl:with-param name="num" select="$total"/> </xsl:call-template> </xsl:template> <!-- 递归模板:逐步移除末尾的零 --> <xsl:template name="strip-trailing-zeros"> <xsl:param name="num"/> <!-- 如果数值大于0且能被10整除,就除以10继续递归 --> <xsl:choose> <xsl:when test="$num > 0 and $num mod 10 = 0"> <xsl:call-template name="strip-trailing-zeros"> <xsl:with-param name="num" select="$num div 10"/> </xsl:call-template> </xsl:when> <!-- 无法整除时输出最终数值 --> <xsl:otherwise> <xsl:value-of select="$num"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
说明:
sum(//linesTotal):和XSLT 2.0一致,先计算出总和。strip-trailing-zeros递归模板:- 每次检查当前数值是否大于0且能被10整除,如果是,就除以10继续递归处理。
- 直到数值无法被10整除(或等于0),就输出这个最终结果。
- 天然支持总和为0的场景,会直接输出0。
测试你的输入XML,两个方案都会输出203,完全符合你的期望。
内容的提问来源于stack exchange,提问作者Girikumar Mathivanan




