Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAVA element.getElementsByTagName Restrict to Top Level

Tags:

I have an XML file as follows:

<rootNode>
    <link>http://rootlink/</link>
    <image>
        <link>http://imagelink/</link>
        <title>This is the title</title>
    </image>
</rootNode>

The XML Java code using DOM is as follows:

NodeList rootNodeList = element.getElementsByTagName("link");

This will give me all of the "link" elements including the top level and the one inside the "image" node.

Is there a way to just get the "link" tags for rootNode within one level and not two such as is the case for the image link? That is, I just want the http://rootlink/ "link".

like image 481
user152090 Avatar asked Aug 06 '09 21:08

user152090


People also ask

What is getElementsByTagName in Java?

getElementsByTagName(String name) Returns a NodeList of all descendant Elements with a given tag name, in document order. NodeList. getElementsByTagNameNS(String namespaceURI, String localName) Returns a NodeList of all the descendant Elements with a given local name and namespace URI in document order.

What does getElementsByTagName do?

getElementsByTagName() method returns a live HTMLCollection of elements with the given tag name. All descendants of the specified element are searched, but not the element itself. The returned list is live, which means it updates itself with the DOM tree automatically.

How to get Element by tag HTML?

You access an element by tag with the getElementsByTagName() method. For our tag example, we're using article elements. Just like accessing an element by its class, getElementsByTagName() will return an array-like object of elements, and you can modify every tag in the document with a for loop.


4 Answers

You could use XPath:

XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
NodeList links = (NodeList) xpath.evaluate("rootNode/link", element,
    XPathConstants.NODESET);
like image 200
McDowell Avatar answered Oct 23 '22 05:10

McDowell


I couldn't find any methods to do that either so I wrote this helper function,

 public static List<Element> getChildrenByTagName(Element parent, String name) {
    List<Element> nodeList = new ArrayList<Element>();
    for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
      if (child.getNodeType() == Node.ELEMENT_NODE && 
          name.equals(child.getNodeName())) {
        nodeList.add((Element) child);
      }
    }

    return nodeList;
  }
like image 41
ZZ Coder Avatar answered Oct 23 '22 05:10

ZZ Coder


If you can use JDOM instead, you can do this:

element.getChildren("link");

With standard Dom the closest you can get is to iterate the child nodes list (by calling getChildNodes() and checking each item(i) of the NodeList, picking out the nodes with the matching name.

like image 38
Rich Seller Avatar answered Oct 23 '22 05:10

Rich Seller


I know this is an old question, but nonetheless I have an alternative solution to add.

It's not the most efficient, but works:

Get all the children using getElementsByTagName, then just check each one has the same parent to the one you started with.

I use this because I have a set of results, each result can have results nested inside it. When I call my Result constructor I need to add any nested results, but as they themselves will look for their own children I don't want to add children to the current level (their parent will add them).

Example:

NodeList children = resultNode.getElementsByTagName("result");
for(int i = 0; i<children.getLength(); i++){
   // make sure not to pick up grandchildren.
   if(children.item(i).getParentNode().isSameNode(resultNode)){
        addChildResult(new Result((Element)children.item(i)));
    }
}

Hope this helps.

like image 37
ThePerson Avatar answered Oct 23 '22 07:10

ThePerson