在XSLT中用逗号作为小数分隔符汇总数字?

时间:2009-03-15 15:35:56

标签: xml xslt sum decimalformat

我有一个XML文件,其中的数字是逗号分隔的

<foo>
  <bar val="1,23"/>
  <bar val="4,56"/>
  <bar val="7,89"/>
</foo>

我想在XSLT中对/foo/bar/@val值进行总结,但我对格式有点不满意。有谁知道什么是正确的语法?

3 个答案:

答案 0 :(得分:6)

我猜,"val"属性中指定的值是一个逗号而不是小数点的数字。

可以使用多种解决方案

<强>予。 XSLT 1.0

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 >
  <xsl:output method="text"/>
<!--                                           -->  
    <xsl:template match="foo">
      <xsl:variable name="vrtfBars">
        <xsl:for-each select="bar">
          <bar val="{translate(@val, ',', '.')}"/>
        </xsl:for-each>
      </xsl:variable>
<!--                                           -->
      <xsl:value-of select=
       "sum(ext:node-set($vrtfBars)/*/@val)"/>
    </xsl:template>
</xsl:stylesheet>

应用于最初提供的XML文档

<foo>
    <bar val="1,23"/>
    <bar val="4,56"/>
    <bar val="7,89"/>
</foo>

产生想要的结果

13.68

<强> II。 XSLT 2.0

此转化

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="f xs"
 >
 <xsl:output method="text"/>
<!--                                           -->
 <xsl:template match="foo">
  <xsl:sequence select=
   "sum(bar/@val/number(translate(., ',', '.')))" 
   />
 </xsl:template>
</xsl:stylesheet>

应用于同一XML文档时,会产生相同的正确结果

13.68

<强> III。 FXSL 2.x

此转化

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:f="http://fxsl.sf.net/"
 xmlns:my="my:fun"
 exclude-result-prefixes="my f xs"
 >
   <xsl:import href="../f/func-transform-and-sum.xsl"/>
<!--                                           -->
 <xsl:output method="text"/>
<!--                                           -->
 <xsl:template match="foo">
  <xsl:sequence select=
   "sum(
        f:transform-and-sum(my:makeNum(), bar/@val )
        )" 
   />
 </xsl:template>
<!--                                           -->
 <xsl:function name="my:makeNum" as="xs:double">
   <xsl:param name="psNum" as="xs:string"/>
<!--                                           -->
   <xsl:sequence select="number(translate($psNum, ',', '.'))"/>
 </xsl:function>
<!--                                           -->
 <xsl:function name="my:makeNum" as="element()">
   <my:makeNum/>
 </xsl:function>
<!--                                           -->
 <xsl:template match="my:makeNum" as="xs:double" mode="f:FXSL">
   <xsl:param name="arg1" as="xs:string"/>
<!--                                           -->
   <xsl:sequence select="my:makeNum($arg1)"/>
 </xsl:template>
</xsl:stylesheet>

应用于同一XML文档时会产生相同的正确结果

13.68

最后一个解决方案更灵活,并且在求和之前需要更复杂的值转换时可以成功使用。

答案 1 :(得分:3)

假设与Dimitre相同,则表示逗号用作小数分隔符,而不是整数列表的分隔符。

没有EXSLT节点集扩展的纯XSLT 1.0:

<xsl:template match="foo">
  <xsl:call-template name="sum">
    <xsl:with-param name="node" select="bar[1]"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="sum">
  <xsl:param name="node"/>
  <xsl:param name="sum" select="0"/>
  <xsl:choose>
    <xsl:when test="$node">
      <xsl:call-template name="sum">
        <xsl:with-param name="node" select="$node/following-sibling::bar[1]"/>
        <xsl:with-param name="sum" select="$sum + translate($node/@val, ',', '.')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$sum"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

答案 2 :(得分:2)

我觉得我说了很多,但是需要重复一遍:XML的重点在于它以易于分析的形式提供数据。包含无法解析为XML的数据的XML毫无意义;如果可能的话,你应该修改你的XML或使用不同的格式。