I have the following xml
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<abc:root-example xmlns:abc="http://www.example.com/abc">
<abc:test-object Name="DesiredObject">
<root xmlns="http://www.example.com">
<value>Hello world</value>
</root>
</abc:test-object>
</abc:root-example>
and the following java code
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFilePath.toFile());
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
@Override
public String getNamespaceURI(String s) {
if (s.equals("abc")) {
return "http://www.example.com/abc";
}
return null;
}
@Override
public String getPrefix(String s) {
return null;
}
@Override
public Iterator<String> getPrefixes(String s) {
return null;
}
});
XPathExpression expr = xpath.compile("//abc:test-object/root");
Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
The final node here always ends up being null. If I remove xmlns="http://www.example.com" from the root node, then the evaluation returns the expected node. It's unclear to me how I properly format the XPath request to get the node. I believe it has something to do with root using a different default namespace, but am having difficult figuring it out.
ex:rootin XPath and have your API (e.g.getNamespaceURI) return the URIhttp://www.example.comfor that prefixex.rootin XPath if the element has that local name, in XPath 2 and later you can do that by declaring a default element namespace but obviously you can have only one so with e.g.<foo xmlns="http://example.com/"><bar xmlns="http://example.org/"/></foo>your XPath needs to use a prefix or wildcard for one of them.