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 ?
The problem is that variables are immutable in xslt. After setting it is not possible to change it.
So you assign citizenTotal = 0. Although you make another "assignment" of variable with the same name in for-each you are - in fact - declaring a new variable in scope of that cycle of loop. When you exit for-each you are out of the scope of it - you got just the variable you declared before that loop and it is set to zero.
If you need total number of all citizens you could do it without cycle with xpath count(//Citizens/Category/Citizen)