我使用Dom4J来解析一些Maven Pom文件。当我使用没有默认命名空间的Pom文件时,一切正常。例如:
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()
但是如果我的Pom文件定义了默认命名空间,它就会停止工作:
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()
奇怪的是pom.selectSingleNode("/project")
工作正常。
如何让我的xpath查询与默认命名空间一起使用?我想查询"/project/groupId"
并获取groupId节点。
答案 0 :(得分:1)
像这样:
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);
<强>更新强>
仔细观察DOM4J代码之后,如果你能够容忍设置全局命名空间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);
更加本地化的解决方案是使用SAXReader
并使用专门的DocumentFactory
配置它,而不是全局的。
答案 1 :(得分:0)
我的hacky解决方案只是在创建Dom对象之前删除pom文件的命名空间。不是很漂亮,但它运作良好,生活还在继续。