Velocity Reviews > XML > Node Counting Problems

# Node Counting Problems

parksch2@hotmail.com
Guest
Posts: n/a

 02-08-2005
I've spent quite a bit of time (way more than I'd like) today looking
for an answer to what I thought would be a simple question. I simply
need to get the count of items within some nodes up to the current node
(previous or previous-sibling related). For example, here is some
sample XML I have to work with:

<ITEM>
<CHILD>
<ITEM>
<CHILD />
<CHILD />
</ITEM>
<ITEM>
<CHILD />
<CHILD />
<CHILD />
</ITEM>
<ITEM>
<CHILD /> <<-- current node
</ITEM>
<ITEM>
<CHILD />
</ITEM>
</CHILD>
</ITEM>

Let's say the current node is as noted above. How do I get the count of
the previous CHILD nodes? In this case the number I'm looking for is 5.
Any help would be greatly appreciated!

David Carlisle
Guest
Posts: n/a

 02-08-2005

count(preceding-sibling::CHILD) + count(../preceding-sibling::ITEM/CHILD)

David

Paul R
Guest
Posts: n/a

 02-08-2005
count(preceding::CHILD)

parksch2@hotmail.com
Guest
Posts: n/a

 02-08-2005
Hey,

Serious thanks for the fast reply. For some reason
"count(../preceding-sibling::ITEM/CHILD)" returns 0 and my count starts
over every time the template executes. Also, will this example work
only if the current node was the 3rd node or will it work at anytime in
the set?

David Carlisle
Guest
Posts: n/a

 02-08-2005

> "count(../preceding-sibling::ITEM/CHILD)" returns 0 `

Then your structure isn't as you showed.

> Also, will this example work only if the current node was the 3rd node o

as you can see there is nothing special about 3 in teh expression it
will work on any node.

Your description was a little vague, I see someone else suggested
count(preceding::CHILD)
which might also be what you want (although it won't in general give the
same answer as the expression I gave).

David

parksch2@hotmail.com
Guest
Posts: n/a

 02-09-2005
Hi David,

You are correct in that I provided a slightly incorrect XML example.
Sorry. Your example works perfectly with the sample I originally
posted. For some reason I can't seem to get it working on my actual XML
though. I tried playing around with the statement but I still can't get
following XML?

<?xml version="1.0" encoding="UTF-8"?>
<ITEM>
<ITEM />
<ITEM />
<ITEM />
<ITEM />
</ITEM>
<ITEM>
<ITEM />
<ITEM />
<ITEM />
</ITEM>
<ITEM>
<ITEM />
</ITEM>
<ITEM>
<ITEM />
<ITEM />
<ITEM />
<ITEM />
</ITEM>

parksch2@hotmail.com
Guest
Posts: n/a

 02-09-2005
Hi David,

You are correct in that I provided a slightly incorrect XML example.
Sorry. Your example works perfectly with the sample I originally
posted. For some reason I can't seem to get it working on my actual XML
though. I tried playing around with the statement but I still can't get
following XML?

<?xml version="1.0" encoding="UTF-8"?>
<ITEM>
<CHILD>
<ITEM>
<CHILD />
<CHILD />
<CHILD />
<CHILD />
</ITEM>
</CHILD>
<CHILD>
<ITEM>
<CHILD />
<CHILD />
<CHILD />
</ITEM>
</CHILD>
<CHILD>
<ITEM>
<CHILD />
</ITEM>
</CHILD>
<CHILD>
<ITEM>
<CHILD />
<CHILD />
<CHILD />
<CHILD />
</ITEM>
</CHILD>
</ITEM>

parksch2@hotmail.com
Guest
Posts: n/a

 02-09-2005
Hi Paul,

For some reason this returns an extremely large number. Maybe because
there are parent nodes named the same?

David Carlisle
Guest
Posts: n/a

 02-09-2005
<ITEM>
<ITEM />
<ITEM />
<ITEM />
<ITEM />
</ITEM>
<ITEM>
<ITEM />
<ITEM />
<ITEM />
</ITEM>
<ITEM>

so, the ITEM's you want to count (the leaf ones) are second cousins not
first cousins:

Or if all this going up and down is too tiresome (and you are doing this
in xslt not in some Xpath-API) you could just use

<xsl:number level="any" count="ITEM[not(*)]"/>

which will generate a running count of all the leaf ITEM nodes to the
current position.

David

parksch2@hotmail.com
Guest
Posts: n/a

 02-09-2005
David,

count(../preceding-sibling::ITEM) +

Perfect! Thanks so much! One last question:

Let's say I would now like to count the same ITEM nodes, but this time
only count the ITEM nodes that have MENU/ITEM children themselves. I
tried this and it doesn't work:

Again, thanks so much for your help!