尝试将XPath与具有为根节点声明的默认命名空间的XML文件一起使用。
示例代码:
final SAXBuilder builder = new SAXBuilder();
final Document document = builder.build(originalFile);
final XPathFactory xFactory = XPathFactory.instance();
final String expression = String.format("//section[@label='%s']/section/section", LABEL);
final XPathExpression<Element> sectionExpression = xFactory.compile(expression, Filters.element());
final List<Element> sections = sectionExpression.evaluate(document);部分是空的。
XML片段
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://www.stellent.com/sitestudio/Project/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.stellent.com/sitestudio/Project/ http://www.stellent.com/sitestudio/ss_project_schema.xsd">
<section label="Index">
<section label="xyz">
<section label="child">
...
</section>
</section>
</section>
</project>删除xmlns="http://www.stellent.com/sitestudio/Project/"是有效的,但不是解决方案!
为什么XPath不能知道这个默认名称空间?还有,它为什么要在乎?
更好的是,我怎样才能笼统地解决这个问题呢?
谢谢你的洞察力。
发布于 2014-07-04 12:22:57
JDOM正在做正确的事情。这是一个常见问题,不仅适用于JDOM,而且适用于一般的XPath。The XPath规范(在某种程度上)是明确的(我已经用粗体表示了相关部分)。
节点测试中的QName将使用表达式上下文中的命名空间声明展开为扩展名称。这与开始标记和结束标记中元素类型名称的扩展方式相同,只是使用xmlns声明的默认名称空间不使用:如果QName没有前缀,那么名称空间URI为null (属性名称的展开方式与此相同)。如果QName的前缀在表达式上下文中没有名称空间声明,则会发生错误。
从XPath的角度来看,这意味着XPath表达式中规则的命名空间处理实际上与XML中的节点不同。对于所有需要为表达式定义(重复)名称空间上下文的XPath表达式,用于表达式的前缀实际上完全独立于实际XML中使用的前缀。
您需要为默认名称空间“发明”名称空间前缀,并在表达式中使用该前缀(在这里,我发明了名称空间前缀ns):
final String expression = String.format("//ns:section[@label='%s']/ns:section/ns:section", LABEL);
final XPathExpression<Element> sectionExpression = xFactory.compile(expression, Filters.e, null,
Namespace.getNamespace("ns", "http://www.stellent.com/sitestudio/Project/"))https://stackoverflow.com/questions/24573282
复制相似问题