简单了解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 相关文章推荐
javaScript对文字按照拼音排序实现代码
Dec 27 Javascript
window resize和scroll事件的基本优化思路
Apr 29 Javascript
jQuery qrcode生成二维码的方法
Apr 03 Javascript
DOM 事件的深入浅出(一)
Dec 05 Javascript
BootStrap Fileinput初始化时的一些参数
Dec 30 Javascript
jQuery实现验证码功能
Mar 17 Javascript
使用 Vue.js 仿百度搜索框的实例代码
May 09 Javascript
JS简单实现数组去重的方法分析
Oct 14 Javascript
详解50行代码,Node爬虫练手项目
Apr 22 Javascript
mpvue实现左侧导航与右侧内容的联动
Oct 21 Javascript
vue3.0自定义指令(drectives)知识点总结
Dec 27 Vue.js
vue判断按钮是否可以点击
Apr 09 Vue.js
深入理解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
多文件上传的例子
2006/10/09 PHP
php中iconv函数使用方法
2008/05/24 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
2013/06/03 PHP
PHP获取POST数据的几种方法汇总
2015/03/03 PHP
smarty模板引擎之内建函数用法
2015/03/30 PHP
Yii2 ActiveRecord多表关联及多表关联搜索的实现
2016/06/30 PHP
PHP查看SSL证书信息的方法
2016/09/22 PHP
PHP实现微信JS-SDK接口选择相册及拍照并上传的方法
2016/12/05 PHP
Javascript select下拉框操作常用方法
2009/11/09 Javascript
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
jquery获取tagName再进行判断
2014/05/29 Javascript
jQuery获取父元素及父节点的方法小结
2016/04/14 Javascript
sso跨域写cookie的一段js脚本(推荐)
2016/05/25 Javascript
jQuery给表格添加分页效果
2017/03/02 Javascript
jQuery插件FusionWidgets实现的Bulb图效果示例【附demo源码下载】
2017/03/23 jQuery
微信小程序实现多个按钮toggle功能的实例
2017/06/13 Javascript
js编写简单的计时器功能
2017/07/15 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
2017/08/29 Javascript
vue 添加vux的代码讲解
2017/11/30 Javascript
Node.js readline 逐行读取、写入文件内容的示例
2018/03/01 Javascript
Vue+element 解决浏览器自动填充记住的账号密码问题
2019/06/11 Javascript
JavaScript实现单英文金山打字通
2020/07/24 Javascript
详解vue中使用transition和animation的实例代码
2020/12/12 Vue.js
Python logging模块学习笔记
2014/05/24 Python
python类和继承用法实例
2015/07/07 Python
安装python时MySQLdb报错的问题描述及解决方法
2018/03/20 Python
python爬取哈尔滨天气信息
2018/07/14 Python
Python3爬虫教程之利用Python实现发送天气预报邮件
2018/12/16 Python
Pytorch实现的手写数字mnist识别功能完整示例
2019/12/13 Python
在Anaconda3下使用清华镜像源安装TensorFlow(CPU版)
2020/04/19 Python
Python爬虫小例子——爬取51job发布的工作职位
2020/07/10 Python
Python实现封装打包自己写的代码,被python import
2020/07/12 Python
The Athlete’s Foot新西兰:新西兰最大的运动鞋零售商
2019/12/23 全球购物
大学生农村教师实习自我鉴定
2013/09/21 职场文书
会计专业职业规划:规划自我赢取未来
2014/02/12 职场文书
自考毕业自我鉴定
2014/03/18 职场文书