在XSLT之前使用sum和子字符串

时间:2013-10-28 22:34:06

标签: xml xslt

我有一个包含多个帐户的XML,我正在尝试使用格式分数/ max_score来计算几个分数的总和。

XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="accounts.xsl"?>

<accounts>
    <account active="yes">
        <id>1</id>
        <name>James</name>
        <score>50/100</score>
    </account>
    <account active="yes">
        <id>2</id>
        <name>Caty</name>
        <score>10/100</score>
    </account>
    <account active="yes">
        <id>3</id>
        <name>Acacia</name>
        <score>30/100</score>
    </account>
    <account active="yes">
        <id>4</id>
        <name>James</name>
        <score>50/100</score>
    </account>
    <account active="yes">
        <id>5</id>
        <name>Scoot_5</name>
        <score>40/100</score>
    </account>
</accounts>

和XSLT:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:template match="/">
        <html>
            <body>

                <p>
                    <xsl:value-of select="sum(//accounts/account/score/number(substring-before(.,'/')))"/>  
                </p>

            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

然而,当我运行xml时,它说它有错误并且不返回总和。为什么呢?

2 个答案:

答案 0 :(得分:2)

问题是您的 XSLT 2.0转换在Web浏览器中不起作用,Web浏览器本身只支持XSLT 1.0

有关在XSLT 1.0中对元素进行求和的方法,请参阅Michael Kay对XSLT 1 and sum function的一般想法的回答。有关代码示例,请参阅Dimitre Novatchev对Multiply 2 numbers and then sum with XSLT的回答。有关Web浏览器中XSLT 2.0的实际支持,请参阅Saxon-CE

我喜欢递归方法。以下是它如何适用于您的问题:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="/">
    <html>
      <body>
        <p>
          <xsl:call-template name="sumScores">
            <xsl:with-param name="pList" select="/accounts/account/score"/>
          </xsl:call-template>
        </p>
      </body>
    </html>
  </xsl:template>

  <xsl:template name="sumScores">
    <xsl:param name="pList"/>
    <xsl:param name="pAccum" select="0"/>
    <xsl:choose>
      <xsl:when test="$pList">
        <xsl:variable name="vHead" select="$pList[1]"/>
        <xsl:call-template name="sumScores">
          <xsl:with-param name="pList" select="$pList[position() > 1]"/>
          <xsl:with-param name="pAccum"
                          select="$pAccum + number(substring-before($vHead,'/'))"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$pAccum"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

(信用:来自similar code written by Dimitre Novatchev。)

当使用您的输入XML运行此XSLT 1.0转换时,我们会获得所需的HTML输出:

<html>
   <body>
      <p>180</p>
   </body>
</html>

答案 1 :(得分:1)

似乎@kjhughes在某种程度上证明你使用的是XSLT 1.0处理器并且你在网络浏览器中运行。

您需要一台XSLT 2.0处理器来运行它。如果您确实在Web浏览器中运行,请考虑Saxon-CE,它是目前运行客户端的唯一2.0处理器。