JavaScript-XPath

        JavaScript对于XML的读取,一般有两种方式:1.利用DOM进行读取。2.利用XPath进行。XPath是一门在XML中查找信息的语言,它提供方便的形式,能像访问电脑文件一样访问到XML中的节点。首先我们看看XPath的一些要点。

     本节要点

//1.XPath表达式
//2.IE和W3C使用XPath的差异
//3.alert()和console.log()的差别,alert()执行了obj.toString()
//4.正则表达式test,exec,replace和RegExp.$1的用法
//5.原型.__proto__和prototype的用法

    1.XPath语法(源于W3SHOOL)

        XML代码

<bookstore>
    <book>
          <title lang="eng">Harry Potter</title>
          <price>29.99</price>
    </book>
    <book>
         <title lang="eng">Learning XML</title>
         <price>39.95</price>
    </book>
</bookstore>
        我们以这段XML为例,讲述XPath表达式的用法。

表达式描述
nodename选取此节点的所有子节点。
/从根节点选取。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点。
..选取当前节点的父节点。
@选取属性。

实例

路径表达式结果
bookstore选取 bookstore 元素的所有子节点。
/bookstore

选取根元素 bookstore。

注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book选取属于 bookstore 的子元素的所有 book 元素。
//book选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang选取名为 lang 的所有属性。
谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。


路径表达式结果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng']选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

    2.利用XPath获取节点和节点集

      IE下的XPath

//IE浏览器下的XPath
//IE浏览器的XPath只有两个方式:
//IE9之后貌似不支持以下写法,出现“SCRIPT438: 对象不支持“selectNodes”属性或方法”的错误,解决方法是
//在菜单->工具->选择IE9兼容视图。
//selectSingleNode和selectNodes分别代表查找单个和多个节点
//查找的node数组从0开始
//XPath要和上下文对象相对应。
//xmlDom.documentElement.selectSingleNode("ROOT/PERSON/AGE");是错误的

var xmlDom = getXMLDom("<ROOT><PERSON ID='1'><NAME>user01</NAME><AGE>20</AGE></PERSON><PERSON ID='2'><NAME>user02</NAME><AGE>24</AGE></PERSON><PERSON ID='3'><NAME>user03</NAME><AGE>26</AGE></PERSON></ROOT>");
var node = xmlDom.selectNodes("ROOT/PERSON");

//xmlDom.selectSingleNode("ROOT/PERSON[0]");      //表示第一个节点
//xmlDom.selectSingleNode("ROOT/PERSON[AGE>24]"); //返回AGE大于24的节点
//xmlDom.selectSingleNode("ROOT/PERSON[@ID=2]");  //返回ID=2的节点
//node.firstChild.nodeValue;			  //利用标准DOM获取其中数据。注意获得的是字符串,在进行数学运算时要转化
//node[0].selectSingleNode("NAME");		  //XPath和上下文对应

      W3C下的XPath

      

//W3C中的XPath
//W3C中XPath数组用1开始,这是和IE不同的
//evaluate(xpathText,contextNode,namespaceURLMapper,resultType,result);
//其中5个参数的具体含义是
//xpathtext:表示要计算的XPath表达式的字符串
//contextNode:文档中,对应要计算的表达式的节点,上下文节点。
//namespaceURLMapper:把一个命名空间前缀映射为一个全称命名空间URL的函数。如果不需要就设为null
//resultType:指定了期待作为结果的对象的类型,使用XPath转换来强制结果类型。类型的可能的值是XPathResult对象所定义的常量。
//result:一个复用的XPathResult对象,如果你要创建一个新的XPathResult对象,则为null
//resultType有10个常量;其中FIRST_ORDERED_NODE_TYPE和ORDERED_NODE_ITERATOR_TYPE最为常用
/*
	ANY_TYPE
		把这个值传递给 Document.evaluate() 或 XPathExpression.evaluate() 来指定可接受的结果类型。属性 resultType 并不设置这个值。
	NUMBER_TYPE
		numbervalue 保存结果。
	STRING_TYPE
		stringvalue 保存结果。
	BOOLEAN_TYPE
		booleanValue 保存结果。
	UNORDERED_NODE_ITERATOR_TYPE
		这个结果是节点的无序集合,可以通过重复调用 iterateNext() 直到返回 null 来依次访问。在此迭代过程中,文档必须不被修改。
	ORDERED_NODE_ITERATOR_TYPE
		结果是节点的列表,按照文档中的属性排列,可以通过重复调用 iterateNext() 直到返回 null 来依次访问。在此迭代过程中,文档必须不被修改。
	UNORDERED_NODE_SNAPSHOT_TYPE
		结果是一个随机访问的节点列表。snapshotLength 属性指定了列表的长度,并且 snapshotItem() 方法返回指定下标的节点。节点可能和它们出现在文档中的顺序不一样。既然这种结果是一个“快照”,因此即便文档发生变化,它也有效。
	ORDERED_NODE_SNAPSHOT_TYPE
		这个结果是一个随机访问的节点列表,就像 UNORDERED_NODE_SNAPSHOT_TYPE,只不过这个列表是按照文档中的顺序排列的。
	ANY_UNORDERED_NODE_TYPE
		singleNodeValue 属性引用和查询匹配的一个节点,如果没有匹配的节点则为 null。如果有多个节点和查询匹配,singleNodeValue 可能是任何一个匹配节点。
	FIRST_ORDERED_NODE_TYPE
		singleNodeValue 保存了文档中的第一个和查询匹配的节点,如果没有匹配的节点,则为 null。 


*/


//获取单一节点
var xmlDom = getXMLDom("<ROOT><PERSON ID='1'><NAME>user01</NAME><AGE>20</AGE></PERSON><PERSON ID='2'><NAME>user02</NAME><AGE>24</AGE></PERSON><PERSON ID='3'><NAME>user03</NAME><AGE>26</AGE></PERSON></ROOT>");
var result = xmlDom.evaluate("ROOT/PERSON[1]",xmlDom,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
console.log(result);                            	//返回的是undefined.这里应该是火狐的问题,因为result的类型和值都不是undefined
//console.log(result.toString());					//返回的是[object XPathResult]
//alert(result);									//返回的却是[object XPathResult]
//这说明alert()输出的全是字符串,他将自动调用Obj.toString();在调试时要注意两种方法的配合使用
if(result !== null){
	serializeXML(result.singleNodeValue);			//单一节点
}

//获取节点集
var xmlDom = getXMLDom("<ROOT><PERSON ID='1'><NAME>user01</NAME><AGE>20</AGE></PERSON><PERSON ID='2'><NAME>user02</NAME><AGE>24</AGE></PERSON><PERSON ID='3'><NAME>user03</NAME><AGE>26</AGE></PERSON></ROOT>");
var result = xmlDom.evaluate("ROOT/PERSON",xmlDom,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
var nodes = [];
var next =result.iterateNext();
while(next != null){
	nodes.push(next);
	next =result.iterateNext();
}

    IE和W3C获取节点和节点集的封装

function serializeXML(xmlDom){  
    var xml = null;  
    //DOM2序列化xmlDom  
    if(typeof window.XMLSerializer != "undefined"){  
        xml = (new XMLSerializer).serializeToString(xmlDom);  
    }else if(typeof xmlDom.xml != "undefined"){  
        //IE序列化XMLDOM  
        xml = xmlDom.xml;  
    }  
    return xml;  
}
function getXMLDom(xmlStr){  
    var xmlDom = null;  
    //DOM2获取xmlDom  
    if(typeof window.DOMParser != "undefined"){  
        xmlDom = (new DOMParser).parseFromString(xmlStr,"text/xml");  
        var errors = xmlDom.getElementsByTagName("parsererror");  
        if(errors.length > 0){  
            throw new Error("DOMParser错误!错误信息 :" + errors[0].textContent);    
        }  
    }else if(typeof window.ActiveXObject != "undefined"){  
        //IE获取xmlDom  
        var version = ["MSXML2.DOMDocument6.0","MSXML2.DOMDocument3.0","MSXML2.DOMDocument"];  
        for(var i = 0; i < version.length; i++){  
            try{  
                xmlDom = new ActiveXObject(version[i]);  
            }catch(e){    
            }  
        }  
        xmlDom.loadXML(xmlStr);  
        if(xmlDom.parseError != 0){  
            throw new Error("IEparseDom错误!错误信息 :" + xmlDom.parseError.reason);    
        }  
    }  
    return xmlDom;  
}  


//跨浏览器获取单一节点和节点集的封装
//1.获取单一节点
function getSingleNode(xpath,xmlDom){
	var node = null;
	//先判断W3C
	if(typeof XPathEvaluator != "undefined"){
		var result = xmlDom.evaluate(xpath,xmlDom,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
		node = result.singleNodeValue;
	}else{
		//兼容低版本IE
		//IE低版本数组从0开始
		/\[(\d)\]/g.exec(xpath);
		var num = RegExp.$1;
		xpath = xpath.replace(num,parseInt(num) + 1);
		node = xmlDom.selectSingleNode(xpath);
	}
	return node;
}

//2.获取节点集
function getNodes(xpath,xmlDom){
	var nodes = [];
	//先判断W3C
	if(typeof XPathEvaluator != "undefined"){
		var result = xmlDom.evaluate(xpath,xmlDom,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
		var node = null;
		while((node = result.iterateNext()) != null){
			nodes.push(node);
		}
	}else{
		//兼容低版本IE
		/\[(\d)\]/g.exec(xpath);
		var num = RegExp.$1;
		xpath = xpath.replace(num,parseInt(num) + 1);
		nodes = xmlDom.selectNodes(xpath);
	}
	return nodes;
}
         今天家里有点事,不能学很多。最近很多事影响着我。暑假让我明白一个道理,人是由内向外的,内心是本质,它将潜移默化的影响你。总之,做一个敞亮的人!



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值