Reputation: 35
I have the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<prefix:someName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:prefix="someUri" xsi:schemaLocation="someLocation.xsd">
<prefix:someName2>
....
</prefix:someName2>
</prefix:someName>
And my code looks like this:
private Node doXpathThingy(Document doc) {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new NamespaceContext(){
@Override
public String getNamespaceURI(String prefix) {
if (prefix == null) {
throw new NullPointerException("Null prefix");
}
return doc.lookupNamespaceURI(prefix);
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
});
try {
XPathExpression expr = xPath.compile(xpathString);
return (Node)expr.evaluate(doc, XPathConstants.NODESET);
} catch (Exception e) {
.... }
}
I'm trying to get this to work with any valid xpath. It works with these xpaths:
"prefix:someName"
"."
But NOT with: "prefix:someName2". It returns null.
I guess I'm still not getting something about namespaces, but I don't understand what? I've tried leaving out the prefixes from my xpath but then nothing works at all. I've also checked if the correct uri is returned for the prefix at doc.lookupNamespaceURI(prefix), and it is.
Any help would be greatly appreciated.
Upvotes: 1
Views: 339
Reputation: 163585
The query prefix:XXX
means child::prefix:XXX
, that is, find an element child of the context node whose name is prefix:XXX
. Your context node is the document node at the root of the tree. The document node has a child named prefix:someName
, but it doesn't have a child named prefix:someName2
. If you want to find a grandchild of the document node, try the query */prefix:someName2
.
Upvotes: 2
Reputation: 142222
Can't say I'm familiar with the Java way of doing XPath, but it looks like you are making an XPath query from the root of the document, so what you are seeing is the expected behavior.
Try this to find someName2 anywhere in the doc
//prefix:someName2
or this to find it as the child of someName2
/prefix:someName/prefix:someName2
or this to find it as the direct child of any root element
/*/prefix:someName2
Upvotes: 2