[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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

Subject: [xsl] Counting level of nodes beneath current (in XPATH)
From: "Ragulf Pickaxe" <jawxml@xxxxxxxxxxx>
Date: Tue, 11 Jan 2005 12:02:28 +0000

Hi all,

I have an XML with the following rules (simplified):

X -> Y+
Y -> Z X?
Z -> (textnode)

An example is like this: <X> <Y> <Z>lv 1</Z> <X> <Y> <Z>lv 2</Z> </Y> </X> </Y> <Y> <Z>lv 1</Z> <X> <Y> <Z>lv 2</Z> <X> <Y> <Z>lv 3</Z> </Y> </X> </Y> <Y> <Z>lv 2</Z> <X> <Y> <Z>lv 3</Z> </Y> </X> <X> <Y> <Z>lv 3</Z> <X> <Y> <Z>lv 4</Z> </Y> <Y> <Z>lv 4</Z> </Y> </X> </Y> </X> </Y> </X> </Y> </X>

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,

this solution is not the best:

<xsl:template match="/">
   <xsl:when test="$lv='1'">
     <xsl:apply-templates select="Y[not(X)]" mode="One"/>
   <xsl:when test="$lv='2'">
     <xsl:apply-templates select="Y[not(X/Y/X)]" mode="Two"/>
     <xsl:apply-templates select="Y" mode="Zero"/>

<xsl:template match="Y" mode="One">
 <!-- Do some stuff -->
 <xsl:apply-templates select="Y[not(X)]" mode="One"/>

Thank you! Ragulf Pickaxe :-|

Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

Current Thread