tags:

views:

209

answers:

4

Hello

I have a org.w3c.dom.Node object.

I would like to see if it has any other siblings.

Here's what I have tried:

Node sibling = node.getNextSibling();
if(sibling == null)
    return true;
else
    return false;

HOWEVER, for some reason (possibly due to identation or line spaces in the source XML) I am not getting the expected result.

[Also

 node.getParentNode().getChildNodes().getLength()

is giving a value higher higher than I would expect.]

I welcome your suggestions to improve this code.

EDIT

As suggested below it seems that blank nodes are thwarting my attempts to count the siblings.

The xml looks something like this:

  <a>
        <b>
              <c>I have this node:</c>
              <c>I want to know how many of these there are.</c>
              <c>This is another sibling.</c>
        </b>
        <b>
        </b>

  </a>

Starting from my node (the first <c></c> above), how do I find out the number of other siblings?

+2  A: 

you could count the number of childnodes in the items parent after filtering out the whitespace nodes. (which you probably don't want, but are also probably messing up your expected result).

I can't put it in actual java real quick because i'm not familiar enough with it, but it should be pretty straightforward.

Kris
What is a whitespace node?
Mark
CDATA or text nodes
Murali VP
Likely, the only node you care about is ELEMENT_NODE.
seanmonstar
+1  A: 

I'm not a Java guy, but in C# one way to test an element to see if it has siblings is to use an XPath query:

bool hasSiblings = elm.SelectNodes("../*").Count == 1;

The * selector finds only elements, which keeps you from having to remember that "node" can mean element, text node, processing instruction, or comment. (I'd estimate that in 90% of cases, when someone talking about XML uses the word "node" they really mean "element".)

Robert Rossney
+2  A: 

When you get child nodes from another node, you receive all direct children. This will include Element nodes, Text nodes, and Comment nodes. Most often, you'll only care about Element nodes. So you can check the result of getChildNodes to see if any are ELEMENT_NODE.

An example function for what you wanted to do:

public function isSingleChild(Node node) {
    boolean singleChild = true;
    NodeList siblings = node.getParentNode().getChildNodes();
    for(int i = 0, int len = siblings.getLength(); i < len; i++) {
     if(siblings.item(i).getNodeType() == Node.ELEMENT_NODE) {
      singleChild = false;
      break;
     }
    }

    return singleChild;
}


Just to see what each node type is like:

<div>
    <!-- Comment Node -->
    <p>Element node</p>
    a text node
</div>

Getting the div's childNodes would return 3 nodes, a comment node containing "Comment Node", an Element node of "P", and a Text node of "a text node".

seanmonstar
A: 

Thanks to all for your input.

Here is the code that I used in the end, it is based on seanmonstar's code.

public Boolean isSingleChild(Node node)
{
    int elementNodes = 0;
    NodeList siblings = node.getParentNode().getChildNodes();
    for(int x = 0 ; x < siblings.getLength(); x++)
    {
        if(siblings.item(x).getNodeType() == Node.ELEMENT_NODE)
        {
            elementNodes++;
        }
    }
    if(elementNodes == 1)
         return true;
    else
        return false;
}
java
oi, of course. I forgot to check if the node was the original node.
seanmonstar