The online XPath tester works similar to my code below for the given XML and XPath (doesn't match anything): http://www.xpathtester.com/xpath
import java.io.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
class test {
public static void main(String[] args) throws Exception {
XPathExpression expr = XPathFactory.newInstance().newXPath().compile(
"/A[namespace-uri() = 'some-namespace']"); // This does not select anything, replacing A with * does
// This XPath selects as expected (in all parsers mentioned): /*[namespace-uri() = 'some-namespace']
String xml = "<A xmlns=\"some-namespace\"> </A>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
System.out.println("Number of nodes selected: " + nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("Node name: " + nodes.item(i).getNodeName());
}
}
}
The above code does not select anything regardless of whether the document factory is namespace aware.
Is that according to the XPath standard? Or an implementation nuance?
This resource mentions the below:
Indeed, when the XML document uses the default namespace, the XPath expression must use a prefix even though the target document does not.
To verify that, I changed the XPath to include a prefix like so:
/p:A[namespace-uri() = 'some-namespace']
and added a namespace resolver that returned URI some-namespace for the prefix p, and that worked.
Questions:
1) Is there a way of making XPath expressions without prefixes work on documents that have default namespaces?
2) How does the [second XPath tester][3] work? (This tester doesn't conform to the standard)
Note: In my application, I cannot control the document and XPath that I receive. But both are guaranteed to be valid.