document.evaluate的详细用法
2007-03-16 10:06
337 查看
使用 Greasemonkey 时会遇到的功能最为强大的一个工具就是 evaluate 函数。通过使用XPath这种查询语言,它可以用来寻找页面中的元素,属性和文本。
举个例子来说,如果您想获得某个页面上的全部链接。您也许会想到使用document.getElementsByTagName ('a');但是如果您还要继续检查是否每个链接都具有href属性,因为<a>还可以用来作为锚名称使用,这时,您需要使用Firefox 内建的XPath支持去获取全部具有href属性的<a>元素。
例子: 获取页面上的全部链接
这里,document.evaluate 是关键的部分。 它把 XPath 查询语句作为一个字符串,其它的参数稍后再做解释。 这条 XPath 查询语句可以找到全部具有href属性的<a>元素,并将它们按照随机的顺序依次返回。(这就是说,第一个被返回的元素并一定也是页面上的第一个这样的元素。) 随后,您就可以用 allLinks.snapshotItem(i) 函数访问每一个元素。
XPath表达式所能做到的甚至会使您惊讶。请看下面这个例子,它获取了全部具有title属性的元素。
例子: 获取全部具有title属性的元素
例子: 获取 div 中的 sponsoredlink 类
注意我在 XPath 查询语句外使用了双引号,这样在语句内部就可以使用单引号。
在 document.evaluate 函数中有很多参数。第二个参数 (在前两个例子中都是docoment) 可以是一个元素, XPath 查询只返回包含在这个元素内的元素。所以,如果您已经引用了一个元素(比如, 通过 document.getElementById 或者 通过 document.getElementsByTagName 得到的数组中的一个元素), 那么您就可以限制查询只返回这个元素的子元素。
第三个参数是对一个叫做 namespace resolver 函数的引用, 它只有在工作在 application/xhtml+xml 类型的页面上的用户脚本中是有效的。即使您对它不是很了解也没有关系,因为那种类型的页面不是很多,您可能一次也遇不到。如果您很想知道它是如何使用的,请参考 Mozilla XPath documentation (http://www-jcsu.jesus.cam.ac.uk/~jg307/mozilla/xpath-tutorial.html),那里解释了它的用法。
第四个参数是结果的返回方式。在前面的两个例子中都使用了 XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, 它将结果以随机的方式返回。我使用的几乎全部都是这种方式,但是,出于某种原因,您想让结果以它们在页面上出现的顺序返回,您可以使用 XPathResult.ORDERED_NODE_SNAPSHOT_TYPE 这种方式。Mozilla XPath documentation (http://www-jcsu.jesus.cam.ac.uk/~jg307/mozilla/xpath-tutorial.html)还给出了另外的一些用例。
第五个参数用来合并两次 XPath 查询的结果。 在获得第一次调用 document.evaluate 得到的结果之后,它将两次查询的结果一起返回。在前面的两个例子中,这个参数都用了null,这意味着我们只想获得本次查询的结果。
现在您明白了吗?XPath 既可以很简单,也可以很难,这取决于您要如何使用它。在此我强烈推荐您尽快去阅读 this excellent XPath tutorial (http://www.zvon.org/xxl/XPathTutorial/General/examples.html),从而了解更多的 XPath 语法。至于 document.evaluate 函数的其它参数, 我几乎从来不使用它们。事实上,您可以自己定义一个函数来封装它们。
例子: 自定义的 xpath 函数
在定义了这个函数之后,您就可以调用 xpath('//a[@href]') 来获得某个页面上的全部链接, 或者调用 xpath('//*[@title]') 来获得具有 title 属性的元素。您仍然需要通过 snapshotItem 函数来访问结果中的每一项,这个函数的类型并不是一个规则的Javascript数组。
转自: Dive Into Greasemonkey → 公用模式 → 操作所有具有特定属性的元素
http://wiki.mozcn.org/index.php/Firefox:Dive_Into_Greasemonkey
附:
Mozilla implements much of the DOM 3 XPath. This allows XPath expressions to be run against both HTML and XML documents.
The simplest interface to the XPath is the
b5e2
which returns an object of type
The evaluate function takes a total of five arguments:
Notice that, since HTML does not have namespaces, we have passed in
The result of this expression is an XPathResult object. If we wish to know the type of result returned, we may evaluated the
You can ty running this example on the current document:
Level 2 Headings
Once we iterate to a node, we have access to all the standard Mozilla-supported DOM interfaces on that node. After iterating through all the
A simple example is using the XPath expression
Count Paragraphs
Although Javascript allows us to convert the number to a string for display, the XPath interface will not automatically convert the numerical result if the
Instead it will return
The constants corresponding to the other simple types follow the same naming pattern:
Iterators: An iterator which allows access to one node at at time. The next node can be accessed with the
Snapshots: A static list of nodes that match the XPathExpression, accessed through the
First nodes: Only the first found node matching the XPath expression is returned. This may be accessed through the
For each of these nodeset types, there is a subtype that is guaranteed to retain document order and one that is not. The full list of typecodes that can be passed as a
For example, //XXX - want an example with add and remove nodes and probably also with contextNode != document
Might be designed to select all MathML expressions that are the children of HTML table elements. To assosiate the
Our call to
举个例子来说,如果您想获得某个页面上的全部链接。您也许会想到使用document.getElementsByTagName ('a');但是如果您还要继续检查是否每个链接都具有href属性,因为<a>还可以用来作为锚名称使用,这时,您需要使用Firefox 内建的XPath支持去获取全部具有href属性的<a>元素。
例子: 获取页面上的全部链接
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); // do something with thisLink }
这里,document.evaluate 是关键的部分。 它把 XPath 查询语句作为一个字符串,其它的参数稍后再做解释。 这条 XPath 查询语句可以找到全部具有href属性的<a>元素,并将它们按照随机的顺序依次返回。(这就是说,第一个被返回的元素并一定也是页面上的第一个这样的元素。) 随后,您就可以用 allLinks.snapshotItem(i) 函数访问每一个元素。
XPath表达式所能做到的甚至会使您惊讶。请看下面这个例子,它获取了全部具有title属性的元素。
例子: 获取全部具有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': // this is a link, do something break; case 'IMG': // this is an image, do something else break; default: // do something with other kinds of HTML elements } }
例子: 获取 div 中的 sponsoredlink 类
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); // do something with thisDiv }
注意我在 XPath 查询语句外使用了双引号,这样在语句内部就可以使用单引号。
在 document.evaluate 函数中有很多参数。第二个参数 (在前两个例子中都是docoment) 可以是一个元素, XPath 查询只返回包含在这个元素内的元素。所以,如果您已经引用了一个元素(比如, 通过 document.getElementById 或者 通过 document.getElementsByTagName 得到的数组中的一个元素), 那么您就可以限制查询只返回这个元素的子元素。
第三个参数是对一个叫做 namespace resolver 函数的引用, 它只有在工作在 application/xhtml+xml 类型的页面上的用户脚本中是有效的。即使您对它不是很了解也没有关系,因为那种类型的页面不是很多,您可能一次也遇不到。如果您很想知道它是如何使用的,请参考 Mozilla XPath documentation (http://www-jcsu.jesus.cam.ac.uk/~jg307/mozilla/xpath-tutorial.html),那里解释了它的用法。
第四个参数是结果的返回方式。在前面的两个例子中都使用了 XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, 它将结果以随机的方式返回。我使用的几乎全部都是这种方式,但是,出于某种原因,您想让结果以它们在页面上出现的顺序返回,您可以使用 XPathResult.ORDERED_NODE_SNAPSHOT_TYPE 这种方式。Mozilla XPath documentation (http://www-jcsu.jesus.cam.ac.uk/~jg307/mozilla/xpath-tutorial.html)还给出了另外的一些用例。
第五个参数用来合并两次 XPath 查询的结果。 在获得第一次调用 document.evaluate 得到的结果之后,它将两次查询的结果一起返回。在前面的两个例子中,这个参数都用了null,这意味着我们只想获得本次查询的结果。
现在您明白了吗?XPath 既可以很简单,也可以很难,这取决于您要如何使用它。在此我强烈推荐您尽快去阅读 this excellent XPath tutorial (http://www.zvon.org/xxl/XPathTutorial/General/examples.html),从而了解更多的 XPath 语法。至于 document.evaluate 函数的其它参数, 我几乎从来不使用它们。事实上,您可以自己定义一个函数来封装它们。
例子: 自定义的 xpath 函数
function xpath(query) { return document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); }
在定义了这个函数之后,您就可以调用 xpath('//a[@href]') 来获得某个页面上的全部链接, 或者调用 xpath('//*[@title]') 来获得具有 title 属性的元素。您仍然需要通过 snapshotItem 函数来访问结果中的每一项,这个函数的类型并不是一个规则的Javascript数组。
转自: Dive Into Greasemonkey → 公用模式 → 操作所有具有特定属性的元素
http://wiki.mozcn.org/index.php/Firefox:Dive_Into_Greasemonkey
附:
Using the Mozilla Javascript Interface to XPath
Introduction
This document describes the interface to access XPath functions from javascriptMozilla implements much of the DOM 3 XPath. This allows XPath expressions to be run against both HTML and XML documents.
The simplest interface to the XPath is the
evaluatefunction of the document object,
b5e2
which returns an object of type
XPathResult:
var xpathResult = document.evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result);
The evaluate function takes a total of five arguments:
xpathExpression: A string containing an xpath expression to be evaluated
contextNode: A node in the
documentagainst which the Xpath expression should be evaluated
namespaceResolver: A function that takes a string containing a namespace prefix from the
xpathExpressionand returns a string containing the URI to which that prefix corresponds. This enables conversion between the prefixes used in the XPath expressions and the (possibly different) prefixes used in the document
resultType: A numeric constant indicating the type of result that is returned. These constants are avaliable in the global
XPathResultobject and are defined in the relevaant section of the XPath Spec. For most purposes it's OK to pass in XPathResult.ANY_TYPE which will cause the results of the Xpath expression to be returned as the most natural type
result:An existing
XPathResultto use for the results. Passing
nullcauses a new
XPathResultto be created.
A simple example
A simple use of XPath is to extract the level 2 headings of a HTML document. The XPath Expression in this case is simply//h2. The code for this is then:
var headings = document.evaluate("//h2", document, null, XPathResult.ANY_TYPE,null);
Notice that, since HTML does not have namespaces, we have passed in
nullas the
namespaceResolver. Since we wish to search over the entire document for headings, we have used the
documentobject itself as the
contextNode.
The result of this expression is an XPathResult object. If we wish to know the type of result returned, we may evaluated the
resultTypeproperty of the returned object. In this case that will evaluate to 4, which, as per the ECMAScript language binding for XPath represents a
UNORDERED_NODE_ITERATOR_TYPE. This is the default return type when the result of the XPath expression is a node set. It allows us access to a single node at a time and does not make any promises about the order in which the nodes will be returned. To access the returned nodes, we may use the
iterateNextmethod of the returned object:
var thisHeading = headings.iterateNext(); var alertText = "Level 2 headings in this document are:/n" while (thisHeading) { alertText += thisHeading.textContent + "/n" thisHeading = headings.iterateNext(); } alert(alertText);
You can ty running this example on the current document:
Level 2 Headings
Once we iterate to a node, we have access to all the standard Mozilla-supported DOM interfaces on that node. After iterating through all the
h1elements returned from our expression, any further calls to
iterateNext()will return
null.
Returning results other than node sets
In many situations, the return value of an XPath expression is not a node set but a simpler type: a number, a string or a boolean value. For expressions of this type, we still obtain anXPathResultobject as a result of our call to
document.evaluatebut we must access the
numberValue,
stringValueor
booleanValueproperties of the
XPathResultto retrive our results.
A simple example is using the XPath expression
count(//p)to obtain the number of paragraphs in a HTML document:
var paragraphCount = document.evaluate("count(//p)", document, null, XPathResult.ANY_TYPE, null).numberValue; alert("This document contains " + paragraphCount + " paragraphs"); }
Count Paragraphs
Although Javascript allows us to convert the number to a string for display, the XPath interface will not automatically convert the numerical result if the
stringValueproperty is requested so the following code will not work:
var paragraphCount = document.evaluate("count(//p)", document, null, XPathResult.ANY_TYPE, null).stringValue; alert("This document contains " + paragraphCount + " paragraphs"); }
Instead it will return
NS_DOM_TYPE_ERROR. It is possible to request a specific type of return value by altering the
resultTypeproperty. In order to force a string return type, we can pass the constant
XPathResult.STRING_TYPE, so the following code will work:
var paragraphCount = document.evaluate("count(//p)", document, null, XPathResult.STRING_TYPE, null).stringValue; alert("This document contains " + paragraphCount + " paragraphs"); }
The constants corresponding to the other simple types follow the same naming pattern:
XPathResult.STRING_TYPE: Return the result as a string where possible
XPathResult.NUMBER_TYPE: Return the result as a floating point number where possible
XPathResult.BOOLEAN_TYPE: Return the result as a boolean where possible
Other types of nodesets
In the earlier example of reading all the level 2 headings in a document, the nodeset returned was of typeUNORDERED_NODE_ITERATOR_TYPE. The XPath interface allows nodesets to be returned in a variety of different ways. There are three principal caategories of nodesets that can be returned:
Iterators: An iterator which allows access to one node at at time. The next node can be accessed with the
iterateNext()method of the
XpathResult()object. If the document is modified between the XPath evaluation, the
invalidIteratorStateproperty becomes
true
Snapshots: A static list of nodes that match the XPathExpression, accessed through the
snapshotItem(itemNumber)method of the
XPathResult, where
itemNumberis the index of the node to be retrived. The number of nodes returned can be accessed through the
snapshotLengthproperty. Snapshots do not change with document mutations and so may contain nodes that no longer exist or an incomplete set of results.
First nodes: Only the first found node matching the XPath expression is returned. This may be accessed through the
singleNodeValueproperty of the
XPathResultobject.
For each of these nodeset types, there is a subtype that is guaranteed to retain document order and one that is not. The full list of typecodes that can be passed as a
resultTypeargument is:
XPathResult.UNORDERED_NODE_ITERATOR_TYPE: Iterator, Unordered
XPathResult.ORDERED_NODE_ITERATOR_TYPE: Iterator, Ordered
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE: Snapshot, Unordered
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE: Snapshot, Ordered
XPathResult.ANY_UNORDERED_NODE_TYPE: Single node, Unordered
XPathResult.FIRST_ORDERED_NODE_TYPE: Single node, Ordered
For example, //XXX - want an example with add and remove nodes and probably also with contextNode != document
Using XPath with XML
All the examples so far have been designed to work with HTML documents in which there are no namespaces. In order to use XPath on XML documents, one must provide a function for converting namespace prefixes in the xpath expression to those in the document. Such a function can be provided explicitly or can be created from a node in the target document.Implementing a Namespace Resolver
Namespace resolvers are simply functions that take namespace prefixes from the XPath expression and return the corresponding URI. For example, the expression://html:td/mathml:math
Might be designed to select all MathML expressions that are the children of HTML table elements. To assosiate the
mathml:prefix with the namespace URL
http://www.w3.org/1998/Math/MathMLand
html:with the URL
http://www.w3.org/1999/xhtmlwe can provide a function:
function NSResolver(prefix) { if(prefix == 'html') { return 'http://www.w3.org/1999/xhtml'; } else if(prefix == 'mathml') { return 'http://www.w3.org/1998/Math/MathML' } else { //this shouldn't ever happen return null; } }
Our call to
document.evaluatethen looks like:
document.evaluate("//html:td/mathml:math", document, NSResolver, XPathResult.ANY_TYPE, null);
相关文章推荐
- document.evaluate的详细用法
- document.evaluate的详细用法--使用XPath查找某些节点对象[z]
- document.evaluate的详细用法--使用XPath查找某些节点对象[z]
- cpio用法详细说明
- ofstream和ifstream详细用法
- HTML thead 标签定义和用法详细介绍
- C++ ofstream和ifstream详细用法
- DOS中SET命令的详细用法
- java.util.vector中的vector的详细用法及与list的区别
- java.util.vector中的vector的详细用法
- CString.Format的详细用法(转)
- 超级详细Tcpdump 的用法
- stl之string类用法详细总结
- chmod命令详细用法
- 解释一下document.all的用法
- linux tr的详细用法
- document.forms用法示例介绍
- sed详细用法介绍
- php中simplexml_load_file()函数用法详细
- document.execCommand()用法说明