Reputation: 58103
java - xpath - pom.xml
I am using following pom.xml file as xml dom resource, i want to get value of tag <version>
without iterating in my code that's why i am using xpath but i guess my xpath express is not correct that's why it is not returning any value. any help appreciated.
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("C:\\projects\\pom.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("project/version");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
}
<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>
<groupId>com.dc.app</groupId>
<artifactId>rum</artifactId>
<packaging>war</packaging>
<version>12.54-SNAPSHOT</version>
<name>rum</name>
<description>rum</description>
</project>
Upvotes: 2
Views: 3195
Reputation: 27103
Make a javax.xml.NamespaceContext
and feed it to your xpath:
xpath.setNamespaceContext(ctx);
So:
DocumentBuilderFactory domFactory = DocumentBuilderFactory
.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("blah.pom");
XPath xpath = XPathFactory.newInstance().newXPath();
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("pom", "http://maven.apache.org/POM/4.0.0");
xpath.setNamespaceContext(
new NamespaceContextImpl("http://maven.apache.org/POM/4.0.0",
namespaces));
XPathExpression expr = xpath.compile("/pom:project/pom:version");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getTextContent());
}
yields:
12.54-SNAPSHOT
EDIT: an implementation of the NamespaceContext:
public class NamespaceContextImpl implements NamespaceContext {
private final Map<String, String> namespaces;
private final String defaultNamespaceURI;
public NamespaceContextImpl(String defaultNamespaceURI,
Map<String, String> namespaces) {
this.defaultNamespaceURI = defaultNamespaceURI;
this.namespaces = namespaces;
}
public Iterator getPrefixes(String namespaceURI) {
throw new IllegalStateException("Not Implemented.");
}
public String getPrefix(String namespaceURI) {
throw new IllegalStateException("Not Implemented.");
}
public String getNamespaceURI(String prefix) {
if (prefix == null) {
throw new IllegalArgumentException();
}
if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
}
if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {
return XMLConstants.XML_NS_URI;
}
if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
return defaultNamespaceURI;
}
String result = namespaces.get(prefix);
if (result == null) {
result = XMLConstants.NULL_NS_URI;
}
return result;
}
}
Upvotes: 5