举个例子来说,如果您想获得页面中的全部链接。您也许会想到用 document.getElementsByTagName('a'),但是您还要检查每个元属是否具有 href 属性,因为 <a> 元属还可以用作有名称的锚。
然而可以用 Firefox 内建的 XPath 功能来查找具有 href 属性的 <a> 元属。
例 4.6. 获取页面中的所有链接
var allLinks, thisLink;
allLinks = document.evaluate(
'//a[@href]',
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allLinks.snapshotLength; i++) {
thisLink = allLinks.snapshotItem(i);
// 使用 thisLink
}document.evaluate 方法是关键。它有一个代表 XPath 查询语句的字符串参数以及一些其它参数,接下来解释一下。这条 XPath 查询语句找到了具有 href 属性的 <a> 元属,用随机的次序排列后返回。(也就是说,集合中的第一个元素并一定是页面中的第一个元素。)然后您可以用 allLinks.snapshotItem(i) 方法访问找到的元素。
XPath 表达式所能做到的甚至会使您惊讶。请看下面这个例子,它获取了全部具有 title 属性的元素。
例 4.7. 获取所有具有 title 属性的元素
var allElements, thisElement;
allElements = document.evaluate(
'//*[@title]',
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allElements.snapshotLength; i++) {
thisElement = allElements.snapshotItem(i);
switch (thisElement.nodeName.toUpperCase()) {
case 'A':
// 这是链接,在这里完成您的操作
break;
case 'IMG':
// 这是图片,在这里完成您的操作
break;
default:
// 其他类型的 HTML 元素,在这里完成您的操作
}
}这是另一个 XPath 查询,它获取了具有特定 class 属性的 <div> 元素。
例 4.8. 获取所有 class 为 sponsoredlink 的 <div>
var allDivs, thisDiv;
allDivs = document.evaluate(
"//div[@class='sponsoredlink']",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
for (var i = 0; i < allDivs.snapshotLength; i++) {
thisDiv = allDivs.snapshotItem(i);
// 使用 thisDiv
}附注:在 XPath 查询语句外使用双引号,这样在语句内就可以使用单引号了。
document.evaluate 方法中有很多参数。第二个参数(在前两个例子中都是 document)可以是任意元素。XPath 查询只返回这个元素的子元素结点。如果已有一个元素的引用(比如,从 document.getElementById 或者 document.getElementsByTagName 数组的一项中得到的引用),您就可以限制查询只返回这个元素的子元素。
第三个参数是对名称空间解析函数的引用,只有在 application/xhtml+xml 类型页面执行的用户脚本中才会用到。即使对它不了解也没关系,因为那种类型的页面不是很多,您可能一次也遇不到。如果您很想知道它的用法,Mozilla XPath 文档解释了它的用法。
第四个参数是结果的返回方式。在前面的两个例子中都使用了 XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,它返回的元素是随机次序的。我99%都是使用这种方式,但是,可能出于某种原因,想以在页面上出现的顺序返回结果,您可以使用 XPathResult.ORDERED_NODE_SNAPSHOT_TYPE。Mozilla XPath 文档还提供了一些其他返回方式的例子。
第五个参数用来合并两次 XPath 查询的结果。传入以前调用 document.evaluate 结果,它将返回两次查询的合并结果。在前面的两个例子中,这个参数都用了 null,这意味着我们只想获得本次 XPath 查询的结果。
现在明白了吗?XPath 既可简单,也可难,这就看您怎么用了。我强烈推荐您阅读这个优秀的 XPath 教程,可以学到更多的 XPath 语法。关于 document.evaluate 的其他参数,
我很少用除非您已经在这里看到他们了。事实上,您可以定义一个函数来封装它们。
例 4.9. xpath 函数
function xpath(query) {
return document.evaluate(query, document, null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
}现在您可以简单的调用 xpath('//a[@href]') 来获得页面上的全部链接,或者用 xpath('//*[@title]') 获得具有 title 属性的元素。您仍然需要用 snapshotItem 方法访问结果中的每个元素;它不是一个规则的 Javascript 数组。