简单了解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调试之DOM断点调试法使用技巧分享
Apr 15 Javascript
学习JavaScript设计模式(接口)
Nov 26 Javascript
Node.js Streams文件读写操作详解
Jul 04 Javascript
AngularJs Injecting Services Into Controllers详解
Sep 02 Javascript
js手动播放图片实现图片轮播效果
Sep 17 Javascript
纯js实现画一棵树的示例
Sep 05 Javascript
基于Vue开发数字输入框组件
Dec 19 Javascript
解决vue项目中type=”file“ change事件只执行一次的问题
May 16 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
Oct 10 Javascript
react项目如何使用iconfont的方法步骤
Mar 13 Javascript
如何通过vscode运行调试javascript代码
Jul 24 Javascript
vue2实现provide inject传递响应式
May 21 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
让PHP支持页面回退的两种方法[转]
2007/02/14 PHP
php adodb操作mysql数据库
2009/03/19 PHP
CodeIgniter输出中文乱码的两种解决办法
2014/06/12 PHP
destoon实现商铺管理主页设置增加新菜单的方法
2014/06/26 PHP
PHP合并discuz用户脚本的方法
2015/08/04 PHP
浅谈php+phpStorm+xdebug配置方法
2015/09/17 PHP
PHP异常处理Exception类
2015/12/11 PHP
PHPExcel简单读取excel文件示例
2016/05/26 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
PHP日志LOG类定义与用法示例
2018/09/06 PHP
JavaScript中的style.display属性操作
2013/03/27 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
jQuery实现鼠标可拖动调整表格列宽度
2014/05/26 Javascript
Jquery时间轴特效(三种不同类型)
2015/11/02 Javascript
JavaScript中获取纯正的undefined的方法
2016/03/06 Javascript
vue组件传值的实现方式小结【三种方式】
2020/02/05 Javascript
JavaScript链式调用原理与实现方法详解
2020/05/16 Javascript
Python笔记(叁)继续学习
2012/10/24 Python
Python实现的爬虫功能代码
2017/06/24 Python
Python实现的计算马氏距离算法示例
2018/04/03 Python
Python实现手写一个类似django的web框架示例
2018/07/20 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
python实现最速下降法
2020/03/24 Python
编码实现字符串转整型的函数
2012/06/02 面试题
法律专业应届本科毕业生求职信
2013/10/25 职场文书
学生个人的自我评价分享
2013/11/05 职场文书
高中学生干部学习的自我评价
2014/02/21 职场文书
篮球比赛拉拉队口号
2014/06/10 职场文书
环保公益策划方案
2014/08/15 职场文书
个人党性分析材料
2014/12/19 职场文书
小学教研工作总结2015
2015/05/13 职场文书
三八节祝酒词
2015/08/11 职场文书
保险公司岗前培训工作总结
2015/10/24 职场文书
浏览器常用基本操作之python3+selenium4自动化测试(基础篇3)
2021/05/21 Python
OpenCV绘制圆端矩形的示例代码
2021/08/30 Python
MyBatis-Plus 批量插入数据的操作方法
2021/09/25 Java/Android