简单了解JavaScript操作XPath的一些基本方法


Posted in Javascript onJune 03, 2016

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()返回)。

主要有10中不同的返回类型。每一种就代表XPathResult对象的一个常量。

  • XPathResult.ANY_TYPE     适合于xpath表达式的数据类型
  • XPathResult.ANY_UNORDERED_NODE_TYPE     返回匹配节点的集合,顺序可能和文档中的不一样。
  • XPathResult.BOOLEAN_TYPE 返回boolean类型
  • XPathResult.FIRST_ORDERED_NODE_TYPE 返回文档中匹配节点的第一个节点。
  • XPathResult.NUMBER_TYPE 返回num类型
  • XPathResult.ORDERED_NODE_ITERATOR_TYPE返回匹配节点的集合,顺序和文档中的一样
  • XPathResult.ORDERED_NODE_SNAPSHOT_TYPE返回一个节点集合片段,在文档外捕获节点,这样将来对文档的任何修改不会影响节点集合。节点集合中的顺序要和文档中的一样。
  • XPathResult.STRING_TYPE 返回一个string类型
  • XPathResult.UNORDERED_NODE_ITERATOR_TYPE 返回匹配节点的集合,顺序可能和文档中的不一样。
  • XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE 返回一个节点集合片段,在文档外捕获节点,这样将来对文档的任何修改不会影响节点集合。节点集合中的顺序没有必要和文档中的一样。

介绍了这么多,那么我们该如何使用这些api进行操作呢?
evaluate()函数返回的信息完全依赖于请求的结果类型。
为了执行xpath查询,需要使用XPathEvaluator对象,你可以生成一个新的对象也可以使用内置的对象,如果生成一个新的对象就要初始化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);

在Firefox, Safari, Chrome, and 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); 
  } 
}

命名空间
如果你只是使用xpath在html文档中简单的查询,evaluate()中的命名空间解析器参数一般为null,如果你倾向于使用xpath在包含命名空间的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对象的createNSResovler()方法,然后可以自动的得到一个命名空间解析器。
如:

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浏览器中对xpath的支持
IE8还没有实现DOM Level 3 XPath中定义的接口,但是它对xpath也有一定的支持,IE中的xpath功能主要对xml文档可用,对document的对象不可用。
在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("");

第二种方法通过XMLHttRequest对象进行请求生成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() and 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");
Javascript 相关文章推荐
JS实现不规则TAB选项卡效果代码
Sep 16 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
Nov 01 Javascript
浅谈JavaScript的全局变量与局部变量
Jun 10 Javascript
浅谈toLowerCase和toLocaleLowerCase的区别
Aug 15 Javascript
JavaScript字符串对象
Jan 14 Javascript
基于vue2框架的机器人自动回复mini-project实例代码
Jun 13 Javascript
js移动端事件基础及常用事件库详解
Aug 15 Javascript
详解微信小程序实现WebSocket心跳重连
Jul 31 Javascript
webpack 从指定入口文件中提取公共文件的方法
Nov 13 Javascript
详解Vue中使用插槽(slot)、聚类插槽
Apr 12 Javascript
Java Varargs 可变参数用法详解
Jan 28 Javascript
Javascript实现鼠标移入方向感知
Jun 24 Javascript
深入理解Javascript中的自执行匿名函数
Jun 03 #Javascript
浅谈JavaScript前端开发的MVC结构与MVVM结构
Jun 03 #Javascript
深入理解JavaScript内置函数
Jun 03 #Javascript
浅谈JavaScript的内置对象和浏览器对象
Jun 03 #Javascript
JavaScript浏览器对象之一Window对象详解
Jun 03 #Javascript
浅谈JavaScript 浏览器对象
Jun 03 #Javascript
深入浅析JavaScript中的arguments对象(强力推荐)
Jun 03 #Javascript
You might like
PHP 数组基础知识小结
2010/08/20 PHP
PHP5中新增stdClass 内部保留类
2011/06/13 PHP
探讨各种PHP字符串函数的总结分析
2013/06/05 PHP
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
javascript实现日历控件(年月日关闭按钮)
2012/12/12 Javascript
jquery ui dialog实现弹窗特效的思路及代码
2013/08/03 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
javascript学习笔记(八)正则表达式
2014/10/08 Javascript
jQuery跨域问题解决方案
2015/08/03 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
2016/07/22 Javascript
jQuery事件对象总结
2016/10/17 Javascript
jquery实现图片列表鼠标移入微动
2016/12/01 Javascript
基于vue的下拉刷新指令和滚动刷新指令
2016/12/23 Javascript
js实现二级导航功能
2017/03/03 Javascript
jquery.validate.js 多个相同name的处理方式
2017/07/10 jQuery
JS实现按钮控制计时开始和停止功能
2017/07/27 Javascript
vue-router 源码实现前端路由的两种方式
2018/07/02 Javascript
vue组件挂载到全局方法的示例代码
2018/08/02 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
2019/08/20 Javascript
layui 监听select选择 获取当前select的ID名称方法
2019/09/24 Javascript
[00:47]TI7不朽珍藏III——沙王不朽展示
2017/07/15 DOTA
[01:01]青春无憾,一战成名——DOTA2全国高校联赛开启
2018/02/25 DOTA
python中黄金分割法实现方法
2015/05/06 Python
Python实现破解猜数游戏算法示例
2017/09/25 Python
python字符串切割:str.split()与re.split()的对比分析
2019/07/16 Python
python实现在多维数组中挑选符合条件的全部元素
2019/11/26 Python
python获取array中指定元素的示例
2019/11/26 Python
pandas apply多线程实现代码
2020/08/17 Python
python 可视化库PyG2Plot的使用
2021/01/21 Python
HTML5 canvas画图并保存成图片的jcanvas插件
2014/01/17 HTML / CSS
html5 css3实例教程 一款html5和css3实现的小机器人走路动画
2014/10/20 HTML / CSS
HTML5 history新特性pushState、replaceState及两者的区别
2015/12/26 HTML / CSS
NARS化妆品官方商店:美国彩妆品牌
2017/08/26 全球购物
linux面试题参考答案(4)
2014/09/21 面试题
投标售后服务承诺书
2015/04/29 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书