Matt
Matt

Reputation: 11347

Get XML nodes from certain tree level

I need a method like Document.getElementsByTagName(), but one that searches only tags from a certain level (ie, not nested tags with the same name)

Example file:

<script>
  <something>
    <findme></findme><!-- DO NOT FIND THIS TAG -->
  </something>
  <findme></findme><!-- FIND THIS TAG -->
</script>

Document.getElementsByTagName() simply returns all findme tags in the document.

Upvotes: 4

Views: 3183

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

Use:

/*/findme

This XPath expression selects all findme elements that are children of the top element of the XML document.

This expression:

//findme[count(ancestor::*) = 5]

selects all findme elements in the XML document that have exactly five ancestor - elements -- that is, they all are at "level 6".

Upvotes: 0

Alain Pannetier
Alain Pannetier

Reputation: 9514

Here is an example with XPath

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class TestXPath {

    private static final String FILE = "a.xml" ;
    private static final String XPATH = "/script/findme";
    public static void main(String[] args) {

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        docFactory.setNamespaceAware(true);
        DocumentBuilder builder;
        try {
            builder = docFactory.newDocumentBuilder();
            Document doc = builder.parse(FILE);
            XPathExpression expr = XPathFactory.newInstance().newXPath().compile(XPATH);
            Object hits = expr.evaluate(doc, XPathConstants.NODESET ) ;
            if ( hits instanceof NodeList ) {
                NodeList list = (NodeList) hits ;
                for (int i = 0; i < list.getLength(); i++ ) {
                    System.out.println( list.item(i).getTextContent() );
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

With

<script>
  <something>
    <findme>1</findme><!-- DO NOT FIND THIS TAG -->
  </something>
  <findme>Find this</findme><!-- FIND THIS TAG -->
  <findme>More of this</findme><!-- FIND THIS TAG AS WELL -->
</script>

It yields

Find this
More of this

Upvotes: 5

Mike Thomsen
Mike Thomsen

Reputation: 37506

If you're using DOM, the only way I can think of would be a recursive function that looks at the children of each element.

Upvotes: 1

Related Questions