Reputation: 39443
I'm using Dom4J to parse some Maven Pom files. When I use Pom files without a default namespace, everything works fine. For example:
Document pom = DocumentHelper.parseText(
"<project>" +
" <groupId>xx.gov.xxx.sistema.xxx</groupId>" +
" <artifactId>sis-teste</artifactId>" +
" <packaging>war</packaging>" +
"</project>");
//below works fine
String groupId = pom.selectSingleNode("/project/groupId").getText()
But if my Pom file defines a default namespace, it stops working:
Document pom = DocumentHelper.parseText(
"<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/maven-v4_0_0.xsd\">" +
" <groupId>xx.gov.xxx.sistema.xxx</groupId>" +
" <artifactId>sis-teste</artifactId>" +
" <packaging>war</packaging>" +
"</project>");
//NullPointerException!!!!!!!!!!!!!!!!!!!!
String groupId = pom.selectSingleNode("/project/groupId").getText()
The weird thing is that pom.selectSingleNode("/project")
works fine.
How do I make my xpath query to work with the default namespace? I'd like to query just for "/project/groupId"
and get the groupId node.
Upvotes: 3
Views: 1728
Reputation: 39443
My hacky solution was just to remove the namespace of the pom file before creating the Dom object. Not really beautiful, but it works fine and life's go on.
Upvotes: 0
Reputation: 12817
Like so:
Document pom = DocumentHelper.parseText(
"<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/maven-v4_0_0.xsd\">" +
" <groupId>xx.gov.xxx.sistema.xxx</groupId>" +
" <artifactId>sis-teste</artifactId>" +
" <packaging>war</packaging>" +
"</project>");
Map<String, String> nsContext = new HashMap<>();
nsContext.put("p", "http://maven.apache.org/POM/4.0.0");
XPath xp = pom.createXPath("/p:project/p:groupId");
xp.setNamespaceURIs(nsContext);
String groupId = xp.selectSingleNode(pom).getText();
System.out.println(groupId);
UPDATE
After a little closer look at the DOM4J code, this is possible, if you can tolerate setting a global namespace uri map:
Map<String, String> nsContext = new HashMap<>();
nsContext.put("p", "http://maven.apache.org/POM/4.0.0");
DocumentFactory.getInstance().setXPathNamespaceURIs(nsContext);
Document pom = DocumentHelper.parseText(
"<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/maven-v4_0_0.xsd\">" +
" <groupId>xx.gov.xxx.sistema.xxx</groupId>" +
" <artifactId>sis-teste</artifactId>" +
" <packaging>war</packaging>" +
"</project>");
String groupId = pom.selectSingleNode("/p:project/p:groupId").getText();
System.out.println(groupId);
A more localized solution would be to use a SAXReader
and configure it with a specialized DocumentFactory
, not the global one.
Upvotes: 4