注意:此问题及其答案适用于大多数/所有支持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-element?
编辑:
答案 0 :(得分:2)
第一个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;
此替代版本使用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
作为上下文节点。
在浏览器中试用: