Node Counting Problems

Discussion in 'XML' started by parksch2@hotmail.com, Feb 8, 2005.

  1. Guest

    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!
     
    , Feb 8, 2005
    #1
    1. Advertising

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

    David
     
    David Carlisle, Feb 8, 2005
    #2
    1. Advertising

  3. Paul R Guest

    count(preceding::CHILD)
     
    Paul R, Feb 8, 2005
    #3
  4. Guest

    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?
     
    , Feb 8, 2005
    #4

  5. > "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
     
    David Carlisle, Feb 8, 2005
    #5
  6. Guest

    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
    it working. Can you please help me with the same statement for the
    following XML?

    <?xml version="1.0" encoding="UTF-8"?>
    <MENU>
    <ITEM>
    <MENU>
    <ITEM />
    <ITEM />
    <ITEM />
    <ITEM />
    </MENU>
    </ITEM>
    <ITEM>
    <MENU>
    <ITEM />
    <ITEM />
    <ITEM />
    </MENU>
    </ITEM>
    <ITEM>
    <MENU>
    <ITEM />
    </MENU>
    </ITEM>
    <ITEM>
    <MENU>
    <ITEM />
    <ITEM />
    <ITEM />
    <ITEM />
    </MENU>
    </ITEM>
    </MENU>
     
    , Feb 9, 2005
    #6
  7. Guest

    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
    it working. Can you please help me with the same statement for the
    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>
     
    , Feb 9, 2005
    #7
  8. Guest

    Hi Paul,

    For some reason this returns an extremely large number. Maybe because
    there are parent nodes named the same?
     
    , Feb 9, 2005
    #8
  9. <ITEM>
    <MENU>
    <ITEM />
    <ITEM />
    <ITEM />
    <ITEM />
    </MENU>
    </ITEM>
    <ITEM>
    <MENU>
    <ITEM />
    <ITEM />
    <ITEM />
    </MENU>
    </ITEM>
    <ITEM>



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


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


    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
     
    David Carlisle, Feb 9, 2005
    #9
  10. Guest

    David,

    count(../preceding-sibling::ITEM) +
    count(../../preceding-sibling::ITEM/MENU/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:

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

    Again, thanks so much for your help!
     
    , Feb 9, 2005
    #10
  11. 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:

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


    / selects (using the child axis) so
    .../preceding-sibling::ITEM/MENU/ITEM
    is not the number of items that have ITEM grandchildren, it is the
    number of ITEM grandchildren.

    "that have" is written "[" in Xpath so you want

    count(../preceding-sibling::ITEM[MENU/ITEM]) +
    count(../../preceding-sibling::ITEM/MENU[ITEM/MENU/ITEM])

    David
     
    David Carlisle, Feb 9, 2005
    #11
  12. Guest

    Hmmm, it returns the same number as before, which doesn't make sense.
    It seems as if your example should work, but for some reason it
    doesn't take into account the [MENU/ITEM], it just counts the ITEM
    nodes again.

    Any ideas?
     
    , Feb 9, 2005
    #12
  13. Guest

    Here is example XML for this problem:

    <MENU>
    <ITEM>
    <MENU>
    <ITEM>
    <MENU>
    <ITEM/>
    <ITEM/>
    <ITEM/>
    </MENU>
    </ITEM>
    <ITEM/>
    <ITEM>
    <MENU>
    <ITEM/>
    <ITEM/>
    </MENU>
    </ITEM>
    <ITEM/> <<--current node
    </MENU>
    </ITEM>
    </MENU>

    So from the current node, I'd want it to return 2, meaning 2 ITEM nodes
    before it contained MENU/ITEM...
     
    , Feb 9, 2005
    #13
  14. t seems as if your example should work, but for some reason it
    doesn't take into account the [MENU/ITEM], it just counts the ITEM
    nodes again.

    Any ideas?


    the nodes selected by foo and foo[MENU/ITEM] will be different (and so
    the count() will be different) unless all the foo nodes have MENU/ITEM
    children so if you don't see a difference, you didn't do what you think
    you did.

    David
     
    David Carlisle, Feb 9, 2005
    #14
  15. Guest

    David,

    Exactly right. I got it working. Thanks a ton for the help!

    Chris
     
    , Feb 9, 2005
    #15
  16. Paul R Guest

    Good point. Whoops.
     
    Paul R, Feb 9, 2005
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. wolf
    Replies:
    0
    Views:
    569
  2. Replies:
    0
    Views:
    1,620
  3. Replies:
    0
    Views:
    387
  4. Tjerk Wolterink
    Replies:
    2
    Views:
    1,484
    Dimitre Novatchev
    Aug 24, 2006
  5. edwardfredriks

    counting up instead of counting down

    edwardfredriks, Sep 6, 2005, in forum: Javascript
    Replies:
    6
    Views:
    225
    Dr John Stockton
    Sep 7, 2005
Loading...

Share This Page