1

My input 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>

I had tried the following XSLT to count Citizen irrelevant of 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>

The expected output is 5 , but it gives 0 which is the initiated value outside for-each. I am missing / messing with <xsl:variable/> for its scope. I just tried what I usually do with JSLT where the scope is page by default. Anything like that in XSLT to mention the scope of variable in XSLT ?

4

2 回答 2

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>
于 2013-07-15T06:38:08.733 回答
1

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

因此,您分配了citizenTotal = 0。尽管您在for-each 中对具有相同名称的变量进行了另一个“分配”,但实际上您是在该循环的范围内声明了一个新变量。当你退出 for-each 时,你就超出了它的范围——你只得到了你在那个循环之前声明的变量,它被设置为零。

如果您需要所有公民的总数,则无需使用 xpath 循环即可count(//Citizens/Category/Citizen)

于 2013-07-15T06:38:19.543 回答