RE: [xsl] Counting level of nodes beneath current (in XPATH)

Subject: RE: [xsl] Counting level of nodes beneath current (in XPATH)
From: "Andrew Welch" <ajwelch@xxxxxxxxxxxxxxx>
Date: Tue, 11 Jan 2005 12:21:02 -0000
> What I am interested in, is the level of Y nodes.
> If I wanted the top two levels, I could easily do this in xpath using
> count(ancestor::Y).
> The problem is that I cannot readily count all descendants -
> count(descendant::Y) will not count the number of levels but
> the total
> number of Y nodes that are beneath the current Y node.
> Is there a way for such counting in XPath?
>
> I want all except the buttom 1, 2, 3 or more levels. The exact amount
> determined from a parameter.
>
> I could have something like [not(X)] for leaf nodes,
> [not(X/Y/X)] for the
> the buttom 2 levels (leaf nodes
>
> and one level up, counting from the leaf). But as the number
> of levels are
> to be determined dynamically,

If I've understood you correctly, you want to count the number of <Y>
elements at a given level?

If so the brute force method of using two-passes in a single stylesheet
will work:

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

<xsl:param name="level" select="3"/>

<xsl:variable name="structureWithLevels">
	<xsl:apply-templates mode="addLevels"/>
</xsl:variable>

<xsl:template match="@*|node()" mode="addLevels">
	<xsl:copy>
		<xsl:apply-templates select="@*|node()"
mode="addLevels"/>
	</xsl:copy>
</xsl:template>

<xsl:template match="Y" mode="addLevels">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:attribute name="level">
			<xsl:value-of select="count(ancestor::Y|.)"/>
		</xsl:attribute>
		<xsl:apply-templates mode="addLevels"/>
	</xsl:copy>
</xsl:template>

<xsl:template match="/">
	<div>
		<xsl:copy-of select="$structureWithLevels"/>
		<xsl:value-of
select="count($structureWithLevels//Y[@level = $level])"/>
	</div>
</xsl:template>

</xsl:stylesheet>

Here the level of each <Y> element is added to it using the moded
identity transform - with that information you can then work out what
ever you want.

Cheers
andrew

Current Thread