javascript - XPath 不适用于动态 HTML 文档

标签 javascript xpath

注意:这个问题及其答案对于大多数/所有支持 XPath 的编程语言和库都有效,而不仅仅是 JavaScript!

使用以下代码创建一个非常简单的 HTML 页面(实际代码加载远程页面,但我试图将您的注意力集中在此处的主要问题上):

var dt = document.implementation.createDocumentType("html", "-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd");
var doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", dt);
var src = "<head></head><body></body>";
doc.documentElement.innerHTML = src;

alert(doc.evaluate(".", doc, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue);
alert(doc.evaluate("/body", doc, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue);
alert(doc.evaluate("//body", doc, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue);
alert(doc.evaluate("/html", doc, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue);

第一个 alert() 显示“[object HTMLDocument]”,另一个 alert() 显示“null”。这是为什么?为了让 XPath 查询工作并让它找到 body 元素,我缺少什么?


编辑:

  • 在示例中添加了“//body”
  • 我想我应该提到我使用的是 Opera 12.17。有没有任何解决方法可以使我得到相同的结果?

最佳答案

第一个 XPath 选择文档根(. 是当前上下文)。

第二个为 null,因为根上下文中没有 body。您可以使用:

/html/body

//body

这将为您提供节点。从那里,您可以使用上下文 XPath 表达式或 DOM 方法和属性获取上下文中的子节点。要查看节点名称,您可以使用所选节点上的 nodeName 属性:

doc.evaluate(".", doc, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null)
   .singleNodeValue.nodeName;
doc.evaluate("//body", doc, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null)
   .singleNodeValue.nodeName;

JSFiddle 1

此替代版本使用 DOM 来创建节点。

var head = document.createElement("head");
var body = document.createElement("body");
doc.documentElement.appendChild(head);
doc.documentElement.appendChild(body);

它还强制执行命名空间(在第一个示例中,Chrome 中会忽略该命名空间),因此 XPath 表达式需要包含命名空间映射函数(作为 evaluate 方法的第三个参数,或忽略它们(使用通配符和本地名称测试,如下例所示)。

doc.evaluate(".//*[local-name()='body']", doc.documentElement, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.nodeName

请注意,我还使用了 doc.documentElement 作为上下文节点。

在浏览器中尝试一下:

JSFiddle 2

关于javascript - XPath 不适用于动态 HTML 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24109226/

相关文章:

python - 在 python etree 中使用 XPATH 选择没有特定属性的节点

xpath - 如何在 XPath 中获取相对路径?

javascript - jQuery 塔 git : Add tags using input buttons

javascript - 地形图边缘不可见

javascript - 为什么我的 JavaScript 无法创建这个元素?

xml - 返回与其他同名元素相同路径中的元素值

javascript - 所有第三方 javascript SDK 都可以与 NativeScript 配合使用吗?

javascript - Prop 处理程序不能一致工作?

c# - 使用SelectSingleNode和Xpath时忽略空白

selenium - CSS 和 XPath 选择器有什么区别?就跨浏览器测试的性能而言,哪个更好?