I'm trying to query an XML document with a default namespace. I want to get the text content of a node in the default namespace.
I believe I've set things up correctly. However, I'm not getting results. I've created a NamespaceContext and passed it to the XPath processor. From the output it doesn't look like the context is being referenced. As such, the namespace-aware processor isn't finding the nodes in the default namespace.
When I try the query with a very ugly XPath expression that ignores namespaces, I get the expected result.
I've included an example program, the XML file being queried and the output.
Thanks.
The program
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
public class Example {
public static void main(String[] args) throws IOException, XPathExpressionException {
List<String> pomLines = Files.readAllLines(Paths.get("example.xml"));
String document = String.join(System.lineSeparator(), pomLines);
// XPathFactory xpathFactory = new net.sf.saxon.xpath.XPathFactoryImpl();
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpathNS = xpathFactory.newXPath();
xpathNS.setNamespaceContext(new NamespaceContext() {
@Override
public String getNamespaceURI(String prefix) {
System.out.println("*** getNamespaceURI, prefix='" + prefix + "'");
if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
System.out.println("*** returning a URL");
return "http://maven.apache.org/POM/4.0.0";
}
System.out.println("*** returning NULL_NS_URI");
return XMLConstants.NULL_NS_URI;
}
@Override
public String getPrefix(String namespaceURI) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException("Not supported yet.");
}
});
XPathExpression xpathExpressionNS = xpathNS.compile("/project/name/text()");
String artifactIdNS = xpathExpressionNS
.evaluate(new InputSource(new StringReader(document)));
System.out.println("artifactIdNS='" + artifactIdNS + "'");
XPath xpath = xpathFactory.newXPath();
XPathExpression xpathExpression = xpath
.compile("/*[local-name()='project']/*[local-name()='name']/text()");
String artifactId = xpathExpression.evaluate(new InputSource(new StringReader(document)));
System.out.println("artifactId='" + artifactId + "'");
}
}
The XML document
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-test-repo</artifactId>
<version>0.1.0</version>
</parent>
<artifactId>test-repo-1</artifactId>
<name>test-repo-1</name>
<version>1.1.0</version>
</project>
Actual output
~/temp% java Example
artifactIdNS=''
artifactId='test-repo-1'
I would have expected some lines with ***.