`
LeeYee
  • 浏览: 69841 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

javascript XPath 实现

阅读更多

关于XPath的相关知识可以参看http://www.w3school.com.cn/xpath/index.asp

注意:以下代码的测试环境为FF3.6.3及IE6.0 。chrome浏览器没有测试过,应该不支持。

在进行XPath之前要对xml文档进行加载。如何加载可参看上篇文章。

var oXmlDom = XmlDom();
oXmlDom.load("exam1.xml");

针对IE,当在读取XML文档后,本身的对象提供了两个方法用于接收XPATH表达式。分别是:selectNodes及selectSingleNode,这两个方法是作为oXmlDom.documentElement的方法调用的。相对Mozilla比较简单,当然功能是没有Mozilla实现XPATH的功能强大。

oXmlDom.documentElement.selectNodes(xPath)
oXmlDom.documentElement.selectSingleNode(xPath)

Mozilla实现XPATH的方式则相对比较复杂。需要创建XPathEvaluator对象,然后调用evaluate方法执行XPATH表达式。evaluate包含五个参数:XPath表达式、上下文节点、命名空间解释程序及返回的结果类型,同时在XPathResult中存放结果(通常为null)命名空间解释程序通常留空。返回结果类型有:

XPathResult.ANY_TYPE——返回符合XPath表达式类型的数据;
XPathResult.ANY_UNORDERED_NODE_TYPE——返回匹配节点的节点集合,但顺序可能与文档中不同
XPathResult.BOOLEAN_TYPE——返回布尔值
XPathResult.FIRST_OREDERED_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——返回节点集合快照,但顺序可能与文档中不同

下面针对Mozilla实现selectNodes及selectSingleNode方法。由于oXmlDom.documentElement为Elment对象,那么为了用相同的代码兼容IE及Mozilla,可以将selectNodes及selectSingleNode作为Element的属性。代码如下:

/**
 * 查找匹配XPath表达式的节点(Mozilla实现selectNodes方法;IE自带该方法)
 * 
 * @param sXPath
 *            XPAHT表达式
 * @return 节点集合数组 Array<Element>
 */
Element.prototype.selectNodes = function(sXPath) {
	var oEvaluator = new XPathEvaluator();
	var oResult = oEvaluator.evaluate(sXPath, this, null,
			XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
	var aNodes = new Array();
	if (oResult != null) {
		var oElement = oResult.iterateNext();
		while (oElement) {
			aNodes.push(oElement);
			oElement = oResult.iterateNext();
		}
	}
	return aNodes;
};
/**
 * 查找第一个匹配XPath表达式的节点(Mozilla实现selectSingleNode方法;IE自带该方法)
 * 
 * @param sXPath
 *            XPAHT表达式
 * @return 节点元素对象 instanceof Element is true
 */
Element.prototype.selectSingleNode = function(sXPath) {
	var oEvaluator = new XPathEvaluator();
	var oResult = oEvaluator.evaluate(sXPath, this, null,
			XPathResult.FIRST_ORDERED_NODE_TYPE, null);
	if (oResult != null) {
		return oResult.singleNodeValue;
	} else {
		return null;
	}
};

这样我们就完成了Mozilla对XPath的实现。

当然Mozilla本身实现的XPath的操作要比单纯的IE提供的selectNodes及selectSingleNode方法更强大,而且对与XPath表达式的支持也更好。我们可以再扩充一些方法,但注意了,下面这些方法只能在支持Mozilla的浏览器中使用:

/**
 * 统计匹配指定模式的节点个数(该方法仅限于Mozilla)
 * 
 * @param sXPath
 *            XPAHT表达式
 * @return 返回匹配节点个数。如没有匹配则返回0
 */
Element.prototype.count = function(sXPath) {
	var __count = 0;
	sXPath = "count(" + sXPath + ")";
	var oEvaluator = new XPathEvaluator();
	var oResult = oEvaluator.evaluate(sXPath, this, null,
			XPathResult.NUMBER_TYPE, null);
	if (oResult) {
		__count = oResult.numberValue;
	}
	return __count;
};
/**
 * 判断指定XPath表达式是否有匹配节点(该方法仅限于Mozilla)
 * 
 * @param sXPath
 *            XPAHT表达式
 * @return true|false
 */
Element.prototype.isMatch = function(sXPath) {
	var oEvaluator = new XPathEvaluator();
	var oResult = oEvaluator.evaluate(sXPath, this, null,
			XPathResult.BOOLEAN_TYPE, null);
	return oResult.booleanValue;
};

当然上述方法,如果是在IE中,可以同过IE提供最基本的两个方法解决,这里就不多做赘述。

下面我们最完成的代码做下测试,看下上述编码对与XPath语法的支持情况,为此做如下测试页面

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
#hea {
	border: 1px dotted orange;
}

#xml {
	float: left;
	width: 400px;
	height: 600px;
	border: 1px dotted red;
}

#res {
	float: left;
	border: 1px solid green;
	width: 500px;
	height: 600px;
}
</style>
<script type="text/javascript" src="loadxml.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
	
	function search(xPath) {
		var oXmlDom = XmlDom();
		oXmlDom.onreadystatechange = function() {
			//IE|FF
			if (oXmlDom.readyState == 4 || oXmlDom.readyState == "complete") {

			}
		}
		oXmlDom.load("exam1.xml");
		var aNodes = oXmlDom.documentElement.selectNodes(xPath);
		var sRes = "";
		for ( var index = 0; index < aNodes.length; index++) {
			sRes += aNodes[index].xml + "\r\n";
		}
		var oDiv = document.getElementById('res');
		oDiv.innerHTML = "";
		var xml = document.createTextNode(sRes);
		oDiv.appendChild(xml);
	}
</script>
</head>
<body>
<div id="hea">
XPath表达式:<input type="text" name="sql" id="sql" size="60" /> <input
	type="button" value="search"
	onclick="search(document.getElementById('sql').value);" /></div>
<iframe src="exam1.xml" id="xml"></iframe>
<div id="res"></div>
</body>
</html>

 exam1.xml源文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<exam>
	<no id="1">
		<question1>我喜欢与历史学家交往<q>ceshi</q></question1>
		<question2>我做事进度较慢,但确保成效</question2>
		<value>4</value>
	</no>
	<no id="2">
		<question1>我想要每个人都喜欢我</question1>
		<question2>我一贯努力工作</question2>
		<value>7</value>
	</no>
	<no id="3">
		<question1>我力争第一</question1>
		<question2>我思考自身的长处</question2>
	</no>
	<no id="4">
		<question1>我思考有待改进之处</question1>
		<question2>我是一个偏重情感的人</question2>
	</no>
	<no id="5">
		<question1>我能够接受多种类型的人</question1>
		<question2>我想念我的朋友</question2>
	</no>
	<no id="6">
		<question1>与陌生人交谈使我兴奋</question1>
		<question2>我认为自己很能干</question2>
	</no>
	<no id="7">
		<question1>我通过与新人建立联系获得满足感</question1>
		<question2>竞争与挑战让我感到兴奋</question2>
	</no>
	<no id="8">
		<question1>成为他人的知己使我满足</question1>
		<question2>我信守自己的价值观</question2>
	</no>
</exam>

我们可以在输入框中进行测试。使用XPath语法 进行测试,当然大部分语法都可以在FF中测试通过,但在IE中,显然对Xpath轴 是不支持的,同时对XPath谓语表达式中的last()、position()也是不支持的。

以下是一些测试语法,大家可以试下:

测试XPath表达式
//IE \FF 均测试通过

//no 或者 /exam/no                             选取所有no节点
//no[@id='1']                                      选取no节点属性为1的节点
//no/*                                                 选取no的所有子节点
//no[@*]                                             选取所有带有属性的no节点
//no[value>4]                                     选取no节点下value节点值大于4的no节点
//no/question1/q | //no[@id='2']        选取no下question1中的q节点或着no节点属性为1的节点
//no/question1/text()                         取no节点下所有的question1节点所包含的文本

//IE不支持XPath轴表达式

//ff
//no[last()-1]                                       选取倒数第一个no节点
//no[position()<3]                               选择位置小于3的no节点
child::no                                              选取当前文档所有的no节点
//no/child::question1                          选取no节点下所有的question1节点
//no/child::question1/child::text()       取no节点下所有的question1节点所包含的文本
0
2
分享到:
评论

相关推荐

    xpath2.js:xpath.js-JavaScript中的开源XPath 2.0实现(与DOM无关)

    xpath2.js-XPath 2查询语言的纯JavaScript实现关于xpath2.js是JavaScript中与DOM无关的开源实现。 执行引擎使用规范规定的XML Schema 1.1数据类型进行操作。特征全面的语言支持通过自定义DOMAdapter使用XPath 2.0...

    xpath.js:xpath.js-JavaScript中的开源XPath 2.0实现(与DOM无关)

    ------------------------------------XPath.js - Pure JavaScript implementation of XPath 2.0 parser and evaluator------------------------------------Copyright (c) 2012 Sergey IlinskyDual licensed under ...

    wicked-good-xpath, 纯JS实现DOM级别 3 XPath规范.zip

    wicked-good-xpath, 纯JS实现DOM级别 3 XPath规范 很好的XPath Wicked XPath是谷歌编写的DOM级别 3 XPath规范的纯JavaScript实现。 它为每个浏览器中的HTML文档启用... 我们相信它是JavaScript中最快的XPath实现。命

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

    他们所实现的核心接口就是XPathEvaluator,它包含一些能够使用xpath表达式进行工作的方法,最主要的方法就是evaluate(),它能够接受五个参数1.xpath查询字符串2.指明xpath查询字符串应该从哪个节点开始3.命名空间...

    xpath2:适用于node.js和浏览器的XPath 2.0实现

    基于针对浏览器和node.js的DOM 3 XPath 2.0实现,与DOM无关的XPath 2语言处理器 xpath2软件包API与npm 软件包API兼容 用npm安装 npm install xpath2 运行您的第一个查询 console . log ( xpath2 . evaluate ( "1 + ...

    JavaScript权威指南第五版【新】(犀牛书)

    《JavaScript权威指南》全面介绍了JavaScript语言的核心,以及Web浏览器中实现的遗留和标准的DOM。它运用了一些复杂的例子,说明如何处理验证表单数据、使用cookie、创建可移植的DHTML动画等常见任务。本书还包括...

    JavaScript完全自学宝典 源代码

    13.2.js 跨浏览器兼容的XPath实现。 13.3.xml 使用XSLT实现“Hello World”的XML文件。 13.4.xsl 使用XSLT实现“Hello World”的XSLT文件。 13.5.html 内嵌的XML数据岛。 13.6.html 外嵌的XML...

    de1.7 轻量级的javascript扩展函数库

    de.js是一个轻量级的javascript扩展函数库,通过扩展页面元素的方法和属性、和扩展javascript内置类型的方法来帮助web前端开发人员实现更便捷和高效的编程。以下是主要特点: 支持类似jquery的选择器,同时支持类似...

    XSL中进行字符串替换

    稍熟悉XPATH的人都知道,在XSL中使用translate函数可以将一...当然,使用第(1)种方法有个好处就是可以充分利用javascript强大的字符串处理功能,例如还可以使用正则表达式。这里使用了一个纯XSL模板来实现字符串替换。

    前端项目-jsel.zip

    前端项目-jsel,用于JavaScript对象的Dom3 XPath实现。

    JavaScript实现的级联算法示例【省市二级联动功能】

    主要介绍了JavaScript实现的级联算法,结合省市二级联动下拉菜单功能实例分析了javascript事件响应与元素动态操作实现级联算法的相关技巧,需要的朋友可以参考下

    C#+WPF+CEF网站内容采集工具/JS注入控制/HTML内容解析/图片超链接地址过滤/内容导出

    对应网页动态部分或涉及Iframe框架嵌入,涉及Ueditor等,无法通过XPath路径采集的,则通过Js注入,实现Js调用C#函数,实现内容的完整采集。采集完成后支持可以导出Excel或Xml。本程序适合各种网页内容采集、分析、...

    一个cssQuery对象 javascript脚本实现代码

    原创的一个cssQuery对象,类似于jQuery的$函数通过css选择器选择DOM元素,目前还不支持xPath语法

    爬取当当网实际图书网站数据

    使用scrapy创建爬虫程序、使用BeautifulSoup爬取数据、爬取...但是实际上有些网站的数据是使用JavaScript管理的,一般的scrapy并不能执行JavaScript程序,在后面的项目中将介绍能执行JavaScript程序的爬虫程序技术。

    ExtJS4中文教程2 开发笔记 chm

    JQuery系列教程之XPath选择符 JQuery系列教程之选择符 JQuery自动缩放页面中的图片 JQuery获取浏览器的高度和宽度 jquery获得和设置下拉框值的代码 基于jquery的跨域调用文件 ================================= 7...

    Ajax完全自学手册(PPT)

    第2章 浏览器中的JavaScript Test4Navigator.htm User-Agent检测法 Test4Window1.htm window对象属性 test4Alert.htm 系统对话框 Test4Timeout.htm 时间间隔和暂停 Test4History.htm 浏览器历史 Test4...

    javascript 读取XML数据,在页面中展现、编辑、保存的实现

    首先考虑用什么方法做,考虑到三个方式:...开始学习XPath、XSLT。AJAX用js异步调用一般处理文件(ashx)的方式。 1、实现选择框(通过Ajax读取数据库,绑定数据)的绑定时出现错误,最终发现是在读取XML时使用了异步方式

    Ajax完全自学手册PPT和源代码(ptt格式)

    XPath Example1.xml XPath Writer.xml 开发中实际使用的XML文档 Test4IE XPath.htm IE中的XPath支持 Test Firefox XMl Path.htm Firefox中的XPath支持 Example.xslt 什么是XSLT Test4IE XSLT.htm IE中的XSLT支持 ...

    ASP.NET高级编程:为校园BBS用户注册提供无刷新验证.pptx

    目 录;;;什么是AJAX AJAX(Asynchronous JavaScript and ...在ASP.NET 3.5中,可以直接拖动AJAX控件,像普通控件一样的使用,实现Web页面的无刷新功能。在ASP.NET 3.5中,Web.config文件中已经声明了AJAX功能。;Scrip

Global site tag (gtag.js) - Google Analytics