

新闻资讯
技术学院必须显式声明并绑定命名空间前缀,因XPath 1.0不支持默认命名空间;直接写/*/book会失败,因无前缀元素实际属于{http://example.com/ns}命名空间,而表达式book被解析为无命名空间节点,导致匹配失败。
Java用XPath解析带默认命名空间的XML,关键在于**必须显式声明并绑定命名空间前缀**,因为XPath 1.0(JDK内置支持的版本)不支持无前缀的默认命名空间匹配。
XML中像 这样的默认命名空间,会让所有无前缀的元素都属于该命名空间。而XPath表达式中的 book 被视为“无命名空间的book”,和实际的 {http://example.com/ns}book 不匹配,结果就是查不到节点。
需要两步:一是创建 NamespaceContext 实现类,把前缀(如 ns)映射到URI;二是在XPath编译前设置它。
NamespaceContext nsContext = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
if ("ns".equals(prefix)) return "http://example.com/ns";
return null;
}
public String getPrefix(String namespaceURI) { return null; }
public Iterator getPrefixes(String namespaceURI) { return Collections.emptyIterator(); }
};
XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(nsContext); Node book = (Node) xpath.evaluate("/ns:root/ns:book", doc, XPathConstants.NODE);
比如提取所有 title 元素:
Object result = xpath.evaluate("//ns:title", doc, XPathConstants.NODESET);
NodeList titles = (NodeList) result;
for (int i = 0; i < titles.getLength(); i++) {
System.out.println(titles.item(i).getTextContent());
}
default namespace 简写语法(如 *:book 或省略前缀)getNamespaceURI() 中处理NamespaceContext?可用第三方库如 net.sf.saxon(支持XPath 2.0+)或封装好的 SimpleNamespaceContext(Apache Commons JXPath等)基本上就这些。核心就一条:默认命名空间 ≠ 无命名空间,XPath里必须用前缀指代它。