0

I have some trouble with XPath. For some unknown reason the result I get from my expression is the one from another run of the function.

Here's the constructor of my class:

Wine(Node ndWine){
    try{
     xpath = XPathFactory.newInstance().newXPath();
    }
    catch(Exception e)
    {}

    Node ndName = null;

    try{
        ndName = (Node)xpath.evaluate("//name", ndWine, XPathConstants.NODE);
    }
    catch(Exception e)
    {}
    if (ndName != null)
        name = ndName.getTextContent();
}

And here's the XML:

<cellar>
  <wine>
    <name>Jasnières</name>
  </wine>
  <wine>
    <name>Ballet d'Octobre</name>
  </wine>
</cellar>

In the calling method I have another xpath expression that breaks down the document to the list of <wine> elements. The above code is called for each node.
In the debugger I check that on the second run the ndWine node actually contains data from the second node of the document, but the evaluation always returns the Jasnieres value instead of ballet d'octobre, which I can't understand.

Any idea of the root cause?

2 Answers 2

4

Starting the XPath expression with // makes it an absolute path. Even though you pass in the <wine> element it ignores it and starts at the document root. Add a . in front to make it a relative path:

.//name

Or better yet, avoid the // syntax if you can. It's best to avoid doing a full descendant-or-self search if you know exactly where the <name> elements will be. If they'll always be directly inside of a <wine> element then use this XPath:

name
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that does it! I wasn't aware that even if the source of the XPath evaluation is a specific node it will search through the entire document nonetheless.
0

Try this piece of code

try {                
     expr = xpath.compile("/cellar/wine/name");
     nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
} catch (XPathExpressionException ignored) {}

for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node != null) {
            NodeList childNodes = node.getChildNodes();
            for (int j = 0; j < childNodes.getLength(); j++) {
                Node childNode = childNodes.item(j);
                if (childNode.getNodeType() == Node.TEXT_NODE) {
                    System.out.println(childNode.getNodeValue());
                }
            }
        }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.