JavaScript中XPath操作的基本方法与浏览器兼容性
本文介绍JavaScript中XPath的基本操作方法。在现代浏览器中,通过document.evaluate()执行查询,支持多种返回类型如节点迭代器与快照。针对含命名空间的XML文档,需配置命名空间解析器。此外,文章详述了IE8等旧版浏览器通过selectSingleNode/selectNodes及XML数据岛实现XPath支持的兼容方案。
XPath在JavaScript中的基本应用
Xpath现在很少被我们使用,因为JSON现在很盛行。可是在XML做为数据交换格式的年代,Xpath在我们随机访问大的xml文档结构的时候扮演着非常重要的位置。也许大家现在很多没有注意到,DOM Level 3 XPath指定的接口已经被Firefox,Safari, Chrome, and Opera实现了。他们所实现的核心接口就是XPathEvaluator,它包含一些能够使用xpath表达式进行工作的方法,最主要的方法就是evaluate(),它能够接受五个参数1.xpath查询字符串2.指明xpath查询字符串应该从哪个节点开始3.命名空间解析器(稍后介绍)4.返回的结果类型5.返回的结果应该添加到那个对象上(很少被使用,因为结果主要通过evaluate()返回)。
XPathResult对象定义了10种不同的返回类型常量,每种类型对应特定的查询结果格式。
- XPathResult.ANY_TYPE:适用于任何数据类型,由XPath表达式决定。
- XPathResult.ANY_UNORDERED_NODE_TYPE:返回匹配节点的集合,节点顺序可能与文档中的顺序不一致。
- XPathResult.BOOLEAN_TYPE:返回布尔类型结果。
- XPathResult.FIRST_ORDERED_NODE_TYPE:返回文档中匹配的第一个节点。
- XPathResult.NUMBER_TYPE:返回数值类型结果。
- XPathResult.ORDERED_NODE_ITERATOR_TYPE:返回匹配节点的集合,节点顺序与文档中的顺序保持一致。
- XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:返回节点集合的快照,将节点捕获在文档外部,确保后续对文档的修改不影响该集合。集合中节点的顺序与文档顺序一致。
- XPathResult.STRING_TYPE:返回字符串类型结果。
- XPathResult.UNORDERED_NODE_ITERATOR_TYPE:返回匹配节点的集合,节点顺序可能与文档中的顺序不一致。
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:返回节点集合的快照,将节点捕获在文档外部,确保后续对文档的修改不影响该集合。集合中节点的顺序无需与文档顺序一致。
XPathResult返回类型详解
了解了上述API后,实际使用时,evaluate()函数的返回信息完全取决于请求的结果类型。执行XPath查询需要借助XPathEvaluator对象,可以实例化一个新对象并初始化,或直接使用浏览器内置的对象。
var evaluator = new XPathEvaluator();
//得到第一个div
var result = evaluator.evaluate("//div", document.documentElement, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null);
alert("First div ID is " + result.singleNodeValue.id);
现代浏览器中的evaluate()使用
在Firefox、Safari、Chrome和Opera中,所有文档实例均实现了XPathEvaluator接口。因此,在HTML页面中执行查询时,可直接使用document.evaluate()。若通过XMLHttpRequest或其他机制获取XML文档,同样可以使用evaluate()方法,例如:
//get first div
var result = document.evaluate("//div", document.documentElement, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null);
alert("First div ID is " + result.singleNodeValue.id);
接下来介绍两种返回多节点的方式,先通过实例进行说明:
//get all divs - iterator style
var result = document.evaluate("//div", document.documentElement, null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
if (result){
var node = result.iterateNext();
while(node) {
alert(node.id);
node = node.iterateNext();
}
}
//get all divs - SNAPSHOT style
var result = document.evaluate("//div", document.documentElement, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (result){
for (var i=0, len=result.snapshotLength; i < len; i++) {
alert(result.snapshotItem(i).id);
}
}
命名空间解析器的配置
关于命名空间的处理:如果仅在HTML文档中进行简单的XPath查询,evaluate()中的命名空间解析器参数通常设为null。若需在包含命名空间的XML文档中查询,则需学习如何创建和使用命名空间解析器。除默认命名空间外,每个命名空间URI都映射到特定的前缀,命名空间解析器负责在XPath引擎中建立前缀与URI的映射。第一种生成方法是创建一个接受命名空间前缀为参数并返回对应URL的方法,例如:
function resolver(prefix){
switch(prefix){
case "wrox": return "http://www.wrox.com/";
case "ncz": return "http://www.nczonline.net/";
default: return "http://www.yahoo.com/";
}
}
第二种方法是利用包含命名空间信息的节点来生成解析器。
<books xmlns:wrox="http://www.wrox.com/" xmlns="http://www.amazon.com/">
<wrox:book>Professional JavaScript</book>
</books>
<books>元素包含了所有命名空间信息,可将该节点的引用传递给XPathEvaluator对象的createNSResolver()方法,从而自动获得命名空间解析器。例如:
var evaluator = new XPathEvaluator();
var resolver = evaluator.createNSResolver(xmldoc.documentElement);
使用上述任一方法,即可轻松在包含命名空间的XML文档中进行查询。
var evaluator = new XPathEvaluator();
var resolver = evaluator.createNSResolver(xmldoc.documentElement);
var result = evaluator.evaluate("wrox:book", xmldoc.documentElement,
resolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (result){
alert(result.singleNodeValue.firstChild.nodeValue);
}
注意:如果在包含命名空间的XML文档中执行查询而未提供命名空间解析器,将会导致错误。
IE浏览器的兼容处理方案
关于IE浏览器对XPath的支持:IE8尚未实现DOM Level 3 XPath定义的接口,但提供了有限的XPath支持,主要适用于XML文档,对HTML文档对象不可用。在IE中生成XML文档的方法包括:
function createDocument(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.DOMDocument.6.0",
"MSXML2.DOMDocument.3.0",
"MSXML2.DOMDocument"];
for (var i=0,len=versions.length; i < len; i++){
try {
var xmldom = new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
return xmldom;
} catch (ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
生成文档对象后,可使用loadXML()方法加载内容:
var xmldoc = createDocument();
xmldoc.loadXML("");
第二种方法是通过XMLHttpRequest对象请求生成XML对象。
var xhr = new XMLHttpRequest(),
xmldoc;
xhr.open("get", "data.xml", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status >= 200 && xhr.status < 300){
xmldoc = xhr.responseXML;
}
};
xhr.send(null);
第三种方法是使用<xml>标签,Microsoft称之为“XML数据岛”,示例如下:
<xml id="myXML" src="data.xml"></xml>
随后:
var xmldoc = document.getElementById("myXML").XMLDocument;
XPath支持方面:IE中的XML文档对象提供了两个内置方法以支持XPath:selectSingleNode()和selectNodes()。这两个方法均接受XPath表达式作为参数,分别返回第一个匹配节点和所有匹配节点。关于命名空间支持:
<books xmlns:wrox="http://www.wrox.com/" xmlns="http://www.amazon.com/">
<wrox:book>Professional JavaScript</book>
对于</books>这段XML文档,应采用以下方法进行查询,即首先使用setProperty()设置XML文档的命名空间。
xmldoc.setProperty("SelectionNamespaces",
"xmlns:wrox='http://www.wrox.com/' xmlns='http://www.amazon.com/'");
var book = xmldoc.documentElement.selectSingleNode("wrox:book");
JS在setTimeout或Ajax回调中打开新标签页失败怎么处理
2026-11-05 15:50:12
JS直播协议选型:HLS、FLV与WebRTC的延迟与兼容性对比
2026-11-05 12:16:14
JS实现回到顶部:scrollTop赋值与浏览器兼容性处理
2026-11-04 23:43:35
JS使用classList动态添加、移除和切换CSS类名
2026-11-04 23:40:58
在 D3.js 中实现平滑过渡动画的技巧
2026-11-03 23:46:09
