for-each循环中的XSLT增量变量不起作用

时间:2013-07-15 06:21:32

标签: xml xslt default scope

我的输入XML:

<Citizens>
  <Category type="Plumbers">
    <Citizen>John</Citizen>
  </Category>
  <Category type="Doctors">
    <Citizen>Ram</Citizen>
    <Citizen>Kumar</Citizen>
  </Category>
  <Category type="Farmers">
    <Citizen>Ganesh</Citizen>
    <Citizen>Suresh</Citizen>
  </Category>
</Citizens>

我曾尝试使用以下XSLT来计算与Citizen无关的Category

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:variable name="citizenTotal" select="0" />
        <xsl:for-each select="Citizens/Category">
            <xsl:variable name="currentCount" select="count(Citizen)" />
            <xsl:variable name="citizenTotal" select="$citizenTotal+$currentCount" />
        </xsl:for-each>
        Total Citizen nodes: <xsl:value-of select="$citizenTotal"></xsl:value-of>
    </xsl:template>
</xsl:stylesheet>

预期输出为5,但它给出0,这是for-each之外的启动值。我遗漏了<xsl:variable/>的范围。我只是尝试了我通常用JSLT做的事情,默认情况下范围是page。在XSLT中提到XSLT中的变量范围的任何东西?

2 个答案:

答案 0 :(得分:4)

在XSL 1.0中,您无法增加全局变量。你可以通过

来实现这个目标
    <xsl:for-each select="Citizens/Category">
        <xsl:if test="position()=last()">
             Total Citizen nodes: <xsl:value-of select="position()"/>
       </xsl:if>
    </xsl:for-each>

但是在XSLT 2.0中,您可以通过在名称空间中使用Saxon来获取全局变量

<xsl:stylesheet version="2.0" 
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
            xmlns:saxon="http://saxon.sf.net/" extension-element-prefixes="saxon"
            exclude-result-prefixes="saxon">

创建变量

<xsl:variable name="count" saxon:assignable="yes" select="0"/>

增量

<saxon:assign name="count"><xsl:value-of select="$count+1"/></saxon:assign>

答案 1 :(得分:1)

问题是变量在xslt中是不可变的。设置后无法更改。

所以你指定citizenTotal = 0.虽然你做了另一个&#34;赋值&#34; for-each中具有相同名称的变量 - 实际上 - 在该循环循环的范围内声明 new 变量。当你退出for-each时,你超出了它的范围 - 你只得到你在该循环之前声明的变量,它被设置为零。

如果您需要所有公民的总人数,您可以不使用xpath count(//Citizens/Category/Citizen)

进行循环