使用XSLT在字符串中添加数字

时间:2011-05-01 05:06:59

标签: xslt

我有一个字符串(在变量中),其中包含由空格或逗号分隔的数字列表。 我需要对字符串中的数字求和。 示例字符串“1,2,5,12,3” 或“1 2 5 12 3”

有没有办法在字符串中添加数字并返回总数?

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>