Snippets
Snippets
本文提供了一些XPath代码片段 - 简单的例子,介绍如何基于DOM Level 3 XPath规范中的标准接口提供一些简单的实用程序函数
,以便将XPath功能展示给JavaScript代码。片段是您可以在自己的代码中在现实世界中使用的函数。
特定于节点的评估程序功能
以下自定义实用程序功能可用于评估给定XML节点上的XPath表达式。第一个参数是一个DOM节点或Document对象,而第二个参数是一个定义XPath表达式的字符串。
示例:定义自定义节点特定的evaluateXPath()效用函数
// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator(
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null
var found = [];
var res;
while (res = result.iterateNext())
found.push(res
return found;
}
此功能使用new XPathEvaluator()
构造函数,该函数在Firefox,Chrome,Opera和Safari中受支持,但不在Edge或Internet Explorer中受支持。可能由Edge或Internet Explorer用户访问的Web文档中的脚本应将呼叫替换new XPathEvaluator()
为以下片段:
// XPathEvaluator is implemented on objects that implement Document
var xpe = aNode.ownerDocument || aNode;
在这种情况下,XPathNSResolver的创建可以简化为:
var nsResolver = xpe.createNSResolver(xpe.documentElement
但是请注意,createNSResolver
只有在确定XPath表达式中的名称空间前缀与要查询的文档中的名称空间前缀匹配时(以及没有使用默认名称空间(尽管请参阅document.createNSResolver
以获得解决方法)),才应使用它。否则,你必须提供你自己的XPathNSResolver实现。
如果您使用XMLHttpRequest将本地或远程XML文件读入DOM树(如解析和序列化XML中所述),则evaluateXPath()
应该使用第一个参数req.responseXML
。
示例用法
假设我们有以下XML文档(另请参阅如何创建DOM树以及解析和序列化XML):
示例:用于自定义evaluateXPath()实用程序功能的XML文档
<?xml version="1.0"?>
<people>
<person first-name="eric" middle-initial="H" last-name="jung">
<address street="321 south st" city="denver" state="co" country="usa"/>
<address street="123 main st" city="arlington" state="ma" country="usa"/>
</person>
<person first-name="jed" last-name="brown">
<address street="321 north st" city="atlanta" state="ga" country="usa"/>
<address street="123 west st" city="seattle" state="wa" country="usa"/>
<address street="321 south avenue" city="denver" state="co" country="usa"/>
</person>
</people>
您现在可以使用XPath表达式“查询”文档。尽管漫步DOM树可以获得类似的结果,但使用XPath表达式更快更强大。如果你可以依赖id
属性,document.getElementById()
仍然强大,但它不如XPath强大。这里有些例子。
示例:使用自定义evaluateXPath()实用程序功能的JavaScript代码
// display the last names of all people in the doc
var results = evaluateXPath(people, "//person/@last-name"
for (var i in results)
alert("Person #" + i + " has the last name " + results[i].value
// get the 2nd person node
results = evaluateXPath(people, "/people/person[2]"
// get all the person nodes that have addresses in denver
results = evaluateXPath(people, "//person[address/@city='denver']"
// get all the addresses that have "south" in the street name
results = evaluateXPath(people, "//address[contains(@street, 'south')]"
alert(results.length
docEvaluateArray
下面是一个简单的实用函数,用于将(有序的)XPath结果获取到数组中,而不管是否存在对名称空间解析器的特殊需求等。它避免了document.evaluate()
不需要的情况下更复杂的语法以及需要使用特殊的迭代器XPathResult
(而不是返回一个数组)。
示例:定义一个简单的docEvaluateArray()效用函数
// Example usage:
// var els = docEvaluateArray('//a'
// alert(els[0].nodeName // gives 'A' in HTML document with at least one link
function docEvaluateArray (expr, doc, context, resolver) {
var i, result, a = [];
doc = doc || (context ? context.ownerDocument : document
resolver = resolver || null;
context = context || doc;
result = doc.evaluate(expr, context, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null
for(i = 0; i < result.snapshotLength; i++) {
a[i] = result.snapshotItem(i
}
return a;
}
getXPathForElement
以下函数允许传递一个元素和一个XML文档来查找一个返回该元素的唯一字符串XPath表达式。
示例:定义一个getXPathForElement()效用函数
function getXPathForElement(el, xml) {
var xpath = '';
var pos, tempitem2;
while(el !== xml.documentElement) {
pos = 0;
tempitem2 = el;
while(tempitem2) {
if (tempitem2.nodeType === 1 && tempitem2.nodeName === el.nodeName) { // If it is ELEMENT_NODE of the same name
pos += 1;
}
tempitem2 = tempitem2.previousSibling;
}
xpath = "*[name()='"+el.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']["+pos+']'+'/'+xpath;
el = el.parentNode;
}
xpath = '/*'+"[name()='"+xml.documentElement.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']"+'/'+xpath;
xpath = xpath.replace(/\/$/, ''
return xpath;
}
资源
- XPath