我有一个字符串(在变量中),其中包含由空格或逗号分隔的数字列表。 我需要对字符串中的数字求和。 示例字符串“1,2,5,12,3” 或“1 2 5 12 3”
有没有办法在字符串中添加数字并返回总数?
答案 0 :(得分:3)
这个更短的转变:
<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
解释:递归调用也与文本节点匹配的命名模板。添加了一个标记(附加的逗号)以加速和简化处理。
<强> II。 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函数number()
之前将每个结果标记转换为数字(使用sum()
函数)。
答案 1 :(得分:0)
我不知道XSLT,但通常你会使用空格和逗号分隔字符串作为分隔符 快速搜索后,如果您使用的是XSLT 2.0,我发现您可以使用 tokenize(字符串,分隔符)作为拆分功能。 This page有一个关于如何使用 tokenize 的示例。
答案 2 :(得分:0)
这是一个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>