简单了解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 相关文章推荐
jquery 文本上下无缝滚动,鼠标放上去就停止 小例子
Jun 05 Javascript
JS.findElementById()使用介绍
Sep 21 Javascript
jquery easyui中treegrid用法的简单实例
Feb 18 Javascript
javascript实现表格排序 编辑 拖拽 缩放
Jan 02 Javascript
jQuery实现简洁的导航菜单效果
Nov 23 Javascript
深入分析node.js的异步API和其局限性
Sep 05 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
JS实现标签滚动切换效果
Dec 25 Javascript
Vue中如何实现proxy代理
Apr 20 Javascript
vue-cli 构建骨架屏的方法示例
Nov 08 Javascript
js实现移动端轮播图
Dec 21 Javascript
详解使用webpack+electron+reactJs开发windows桌面应用
Feb 01 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
cache_lite试用
2007/02/14 PHP
PHP闭包(Closure)使用详解
2013/05/02 PHP
使用php清除bom示例
2014/03/03 PHP
ThinkPHP权限认证Auth实例详解
2014/07/22 PHP
ThinkPHP实现二级循环读取的方法
2014/11/03 PHP
浅析php单例模式
2014/11/25 PHP
PHP通过bypass disable functions执行系统命令的方法汇总
2018/05/02 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
JQuery下关于$.Ready()的分析
2009/12/13 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
收集json解析的四种方法分享
2014/01/17 Javascript
JS基于VML技术实现的五角星礼花效果代码
2015/10/26 Javascript
JS和jQuery使用submit方法无法提交表单的原因分析及解决办法
2016/05/17 Javascript
浅谈在js传递参数中含加号(+)的处理方式
2016/10/11 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
2017/02/16 Javascript
jquery.validate.js 多个相同name的处理方式
2017/07/10 jQuery
Vue项目从webpack3.x升级webpack4不完全指南
2019/04/28 Javascript
JS获取本地地址及天气的方法实例小结
2019/05/10 Javascript
vue elementUI使用tabs与导航栏联动
2019/06/21 Javascript
javascript实现前端input密码输入强度验证
2020/06/24 Javascript
[04:10]2016国际邀请赛中国区预选赛第二日TOP10精彩集锦
2016/06/28 DOTA
用Python将一个列表分割成小列表的实例讲解
2018/07/02 Python
Python中format()格式输出全解
2019/04/12 Python
python属于解释型语言么
2020/06/15 Python
Python类的继承super相关原理解析
2020/10/22 Python
CSS3 函数技巧 用css 实现js实现的事情(clac Counters Tooltip)
2017/08/15 HTML / CSS
Linux文件操作命令都有哪些
2016/07/23 面试题
Prototype如何更新局部页面
2013/03/03 面试题
在校硕士自我鉴定
2014/01/23 职场文书
《登鹳雀楼》教学反思
2014/04/09 职场文书
元旦寄语大全
2014/04/10 职场文书
超市优秀员工事迹材料
2014/05/01 职场文书
小学生春游活动方案
2014/08/20 职场文书
2014县委书记四风对照检查材料思想汇报
2014/09/21 职场文书
“四风”查摆问题自我剖析材料
2014/09/27 职场文书
Python 装饰器(decorator)常用的创建方式及解析
2022/04/24 Python