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

问题描述:

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

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

+0

好问题,+1。查看我的答案,获取完整,非常简短的XSLT 1.0解决方案。 :) – 2011-05-01 15:52:30

+0

增加了一个更短,完整的XSLT 2.0解决方案。我的答案现在提供解决方案的解释。 – 2011-05-01 16:12:24

这更短的改造:

<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()函数)。

+0

谢谢。很好的解释。 – user733028 2011-05-01 17:09:08

+0

@ user733028:不客气。 – 2011-05-01 17:10:06

我不知道XSLT,但通常会使用空格和逗号分隔字符串作为分隔符。
快速搜索后,我发现如果您使用的是XSLT 2.0,则可以使用作为分割函数的标记大小(字符串,分隔符)This page举例说明如何使用tokenize

+1

只需添加,如果您的处理器不支持XSLT 2.0,您也可以使用EXSLT的标记化方式 – snoofkin 2011-05-01 08:41:39

+2

完整的XSLT/XPath 2.0代码将是sum(for $ s in tokenize('1 ,2,5,12,3',',')返回号码($ s))'。 – 2011-05-01 09:46:44

下面是一个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> 
+0

谢谢,但解决方案似乎带回了没有分界符(不是总分)的数字列表。 – user733028 2011-05-01 14:57:23

+0

我拿回来...它的作品:) – user733028 2011-05-01 15:01:32