java - getNodeName 匹配 XML 节点,但 XPath 找不到它

标签 java xpath

这感觉像是一个菜鸟问题。

我正在查看一堆操作 XML DOM 的 Java 代码。 (这些类是 JDK 7 附带的常用 org.w3c.dom.Documentjavax.xml.xpath.XPath 类。)它有很多地方看起来像这样:

String expr = "/fixed/path/through/the/hierarchy";

// actual code reuses factory instances, etc
XPath xpath = XPathFactory.newInstance().newXPath();
Node topNode = someDocumentInstance.getFirstChild();
Node node = (Node) xpath.evaluate (expr, topNode, XPathConstants.NODE);

NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
    Node child = children.item(i);
    if (child.getNodeName().equalsIgnoreCase("somePrefix:someTag")) {
        // "return child;" or otherwise break out of the loop
    }
}

这一切都有效。但这个循环似乎是一项乏味的工作;如果我们已经使用 XPath 来获取节点,为什么还要迭代该节点的子节点来查找已知标签?

所以我尝试重写一个部分来直接获取子节点。但使用查询

String expr = "/fixed/path/through/the/hierarchy/somePrefix:someTag";

从不匹配任何内容。我尝试过请求 XPathConstants.NODESET.STRING 等变体,但仍然没有结果。 (无论如何,这些节点应该只有一个。)

我觉得我在这里遗漏了一些非常明显的东西,但是当父查询加上手动循环子项工作时,我无法弄清楚为什么完整查询失败。当我使用这样的查询时,XPath 是否会在 getNodeName() 之外测试节点的某些质量?

我提出的唯一理论是它与 XML 命名空间有关,而该项目中没有使用 XML 命名空间。 (实际上在 DocumentBuilderFactory 实例上有一个对 .setNamespaceAware(false) 的调用,并带有注释“将此功能关闭,否则所有地方都会损坏”。)

最佳答案

如果您在没有命名空间的情况下进行解析,那么您应该将 somePrefix 保留在表达式之外:

String expr = "/fixed/path/through/the/hierarchy/someTag";

原因是 XPath 对 namespace 和本地名称执行匹配,而不是限定名称(这是 getNodeName() 返回的内容)。如果您在 XPath 表达式中添加前缀,XPath 解释器将使用该前缀从其 namespace 映射中检索 namespace 。由于您没有为其提供任何映射,因此将会失败。

此外,如果您要迭代子节点,您可能需要使用 NODESET

关于java - getNodeName 匹配 XML 节点,但 XPath 找不到它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14282126/

相关文章:

sql-server - 在SQL Server 2008中使用XPath/XQuery将一个属性与另一个属性进行匹配

xml - 仅返回XQuery FLWOR序列中的一个元素

python - Selenium获取python的所有属性

java - EJB 和 FLEX

java - JBoss7 : LDAP connectivity issue

sql - 如何为 SQL Server 表中的所有行返回 XML 列中特定属性的值?

python - lxml xpath 不工作

java - 如何在过滤器 ListView- Item-Click 上加载特定 Activity (多个 Intent )?

java - 静态同步方法与非静态同步方法

java - Apache Camel : Proxy code