使用XSLT在字符串中添加数字
我有一个字符串(在一个变量中),其中有由空格或逗号分隔的数字列表。 我需要对字符串中的数字进行求和。 示例字符串“1,2,5,12,3” 或“1 2 5 12 3”使用XSLT在字符串中添加数字
有没有方法在字符串中添加数字并返回总数?
这更短的改造:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()" name="sumStringList">
<xsl:param name="pText" select="."/>
<xsl:param name="pSum" select="0"/>
<xsl:param name="pDelim" select="','"/>
<xsl:choose>
<xsl:when test="not(string-length($pText) >0)">
<xsl:value-of select="$pSum"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vnewList"
select="concat($pText,$pDelim)"/>
<xsl:variable name="vHead" select=
"substring-before($vnewList, $pDelim)"/>
<xsl:call-template name="sumStringList">
<xsl:with-param name="pText" select=
"substring-after($pText, $pDelim)"/>
<xsl:with-param name="pSum" select="$pSum+$vHead"/>
<xsl:with-param name="pDelim" select="$pDelim"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当在下面的XML文档施加:
<t>1,2,5,12,3</t>
产生希望,修正牛逼结果:
23
说明:递归调用命名模板也匹配的文本节点。一个哨兵(附加逗号)被添加来加快和简化处理。
二, XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="pDelim" select="','"/>
<xsl:template match="text()">
<xsl:sequence select=
"sum(for $s in tokenize(.,$pDelim)
return number($s)
)
"/>
</xsl:template>
</xsl:stylesheet>
当在同一个XML文档(上图),这种转变产生同样的希望,正确答案应用:
23
这里我们使用标准的XPath 2.0功能tokenize()
,并且我们必须在最终应用标准XPath函数sum()
之前将每个得到的令牌转换为数字(使用number()
函数)。
谢谢。很好的解释。 – user733028 2011-05-01 17:09:08
@ user733028:不客气。 – 2011-05-01 17:10:06
下面是一个XSLT 1.0溶液
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:variable name="listOfValues" select="'1,2,5,12,3'" />
<xsl:call-template name="splitAndAdd">
<xsl:with-param name="list" select="$listOfValues"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="splitAndAdd">
<xsl:param name="list" />
<xsl:param name="delimiter" select="','"/>
<xsl:param name="total" select="0" />
<xsl:variable name="newList">
<xsl:choose>
<xsl:when test="contains($list, $delimiter)">
<xsl:value-of select="normalize-space($list)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(normalize-space($list),$delimiter)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="token"
select="substring-before($newList, $delimiter)" />
<xsl:variable name="remaining"
select="normalize-space(substring-after($newList, $delimiter))" />
<xsl:variable name="newTotal" select="$total + number($token)" />
<xsl:choose>
<xsl:when test="$remaining">
<xsl:call-template name="splitAndAdd">
<xsl:with-param name="delimiter" select="$delimiter"/>
<xsl:with-param name="list" select="$remaining"/>
<xsl:with-param name="total" select="$newTotal" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$newTotal" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
谢谢,但解决方案似乎带回了没有分界符(不是总分)的数字列表。 – user733028 2011-05-01 14:57:23
我拿回来...它的作品:) – user733028 2011-05-01 15:01:32
好问题,+1。查看我的答案,获取完整,非常简短的XSLT 1.0解决方案。 :) – 2011-05-01 15:52:30
增加了一个更短,完整的XSLT 2.0解决方案。我的答案现在提供解决方案的解释。 – 2011-05-01 16:12:24