如何在 dom4j selectNotes xpath 表达式中使用默认命名空间?
How to use default namespace in dom4j selectNotes xpath expressions?
我正在使用 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 节点。
像这样:
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<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
配置它,而不是全局的。
我的 hacky 解决方案只是在创建 Dom 对象之前删除 pom 文件的名称空间。不是很漂亮,但它工作正常,生活还在继续。
我正在使用 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 节点。
像这样:
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<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
配置它,而不是全局的。
我的 hacky 解决方案只是在创建 Dom 对象之前删除 pom 文件的名称空间。不是很漂亮,但它工作正常,生活还在继续。