javascript
第一百二十六节,JavaScript,XPath操作xml节点
第一百二十六節,JavaScript,XPath操作xml節點
?
學習要點:
1.IE中的XPath
2.W3C中的XPath
3.XPath跨瀏覽器兼容
?
XPath是一種節點查找手段,對比之前使用標準DOM去查找XML中的節點方式,大大降低了查找難度,方便開發者使用。但是,DOM3級以前的標準并沒有就XPath做出規范;直到DOM3在首次推薦到標準規范行列。大部分瀏覽器實現了這個標準,IE則以自己的方式實現了XPath。
?
一.IE中的XPath
在IE8及之前的瀏覽器,XPath是采用內置基于ActiveX的XML DOM文檔對象實現的。在每一個節點上提供了兩個方法:selectSingleNode()和selectNodes()。
selectSingleNode()方法接受一個XPath模式(也就是查找路徑),找到匹配的第一個節點并將它返回,沒有則返回null。
selectSingleNode()方法,查找xml節點,查找單一節點如果有相同的節點只返回第一個節點,有參參數是要查找的節點路徑,此方法只支持IE并且是IE9以下
使用方式
XML DOM對象.selectSingleNode('要查找的節點路徑')
?
上下文節點
上下文節點:我們通過xmlDom這個對象實例調用方法,而xmlDom這個對象實例其實就是一個上下文節點,這個節點指針指向的是根,也就是root元素之前。那么如果我們把這個指針指向user元素之前,那么結果就會有所變化。
通過xmlDom,并且使用root/user的路徑
//通過xmlDom,并且使用root/user的路徑var user = xmlDom.selectSingleNode('root/user');alert(user.tagName); //user通過xmlDom.documentElement,并且使用user路徑,省去了root
//通過xmlDom.documentElement,并且使用user路徑,省去了rootvar user = xmlDom.documentElement.selectSingleNode('user');alert(user.tagName); //user通過xmlDom,并且使用user路徑,省去了root
//通過xmlDom,并且使用user路徑,省去了rootvar user = xmlDom.selectSingleNode('user');alert(user.tagName); //找不到了,出錯?PS:xmlDom和xmlDom.documentElement都是上下文節點,主要就是定位當前路徑查找的指針,而xmlDom對象實例的指針就是在最根上。
?
XPath常用語法
?
通過user[n]來獲取第n+1條節點,PS:XPath其實是按1為起始值的,也就是通過索引位置來獲取對應的標簽
//通過user[n]來獲取第n+1條節點,PS:XPath其實是按1為起始值的 var user = xmlDom.selectSingleNode('root/user[1]'); alert(user.xml);通過text()獲取節點內的值
//通過text()獲取節點內的值 var user = xmlDom.selectSingleNode('root/user/text()'); alert(user.xml); alert(user.nodeValue);通過//user 表示在整個xml獲取到user節點,不關心任何層次,通過雙斜杠獲取節點
//通過//user表示在整個xml獲取到user節點,不關心任何層次 var user = xmlDom.selectSingleNode('//user'); alert(user.xml);通過root//user表示在root包含的層次下獲取到user節點,在root內不關心任何層次,通過指定節點下雙斜杠獲取節點
//通過root//user表示在root包含的層次下獲取到user節點,在root內不關心任何層次 var user = xmlDom.selectSingleNode('root//user'); alert(user.tagName);通過root/user[@id=6]表示獲取user中id=6的節點,通過id獲取指定節點
//通過root/user[@id=6]表示獲取user中id=6的節點 var user = xmlDom.selectSingleNode('root/user[@id=6]'); alert(user.xml);PS:更多的XPath語法,可以參考XPath手冊或者XML DOM手冊進行參考,這里只提供了最常用的語法。
?
selectNodes()方法,查找xml節點,返回相同名稱的節點集合,有參參數是要查找的節點路徑,此方法只支持IE并且是IE9以下
使用方式
XML DOM對象.selectNodes('要查找的節點路徑')
?
二.W3C下的XPath
在DOM3級XPath規范定義的類型中,最重要的兩個類型是XPathEvaluator和XPathResult。其中,XPathEvaluator用于在特定上下文對XPath表達式求值。
XPathEvaluator的方法
| 方法 | 說明 |
| createExpression(e, n) | 將XPath表達式及命名空間轉化成XPathExpression |
| createNSResolver(n) | 根據n命名空間創建一個新的XPathNSResolver對象 |
| evaluate(e, c, n ,t ,r) | 結合上下文來獲取XPath表達式的值 |
W3C實現XPath查詢節點比IE來的復雜,首先第一步就是需要得到XPathResult對象的實例。得到這個對象實例有兩種方法,一種是通過創建XPathEvaluator對象執行evaluate()方法,另一種是直接通過上下文節點對象(比如xmlDom)來執行evaluate()方法。
XPathResult對象
XPathEvaluator類型
第一個方式,首先new?XPathEvaluator類型,然后執行XPathEvaluator類型下的evaluate()方法來創建XPathResult對象
evaluate()方法,創建XPathResult對象有5個參數,1要查找的xml標簽路徑,2上下文節點對象也就是XMLDOM對象,3命名空間求解器(通常是null),4返回結果類型,5保存結果的XPathResult對象(通常是null)。
使用方式:
XPathResult對象.evaluate(要查找的xml標簽路徑,XMLDOM對象,null,返回結果類型,null)
對于返回的結果類型,有10中不同的類型,常用的是紅字的兩個類型
| 常量 | 說明 |
| XPathResult.ANY_TYPE | 返回符合XPath表達式類型的數據 |
| XPathResult.ANY_UNORDERED_NODE_TYPE | 返回匹配節點的節點集合,但順序可能與文檔中的節點的順序不匹配 |
| XPathResult.BOOLEAN_TYPE | 返回布爾值 |
| XPathResult.FIRST_ORDERED_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 | 返回節點集合快照,在文檔外捕獲節點,這樣將來對文檔的任何修改都不會影響這個節點列表 |
PS:上面的常量過于繁重,對于我們只需要學習了解,其實也就需要兩個:1.獲取一個單一節、2.獲取一個節點集合。
兩種方式創建XPathResult對象
使用XPathEvaluator對象創建XPathResult
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //創建XML DOM對象,接收xml字符串//使用XPathEvaluator對象創建XPathResult var eva = new XPathEvaluator(); //創建XPathResult對象 //evaluate()方法,創建XPathResult對象有5個參數,1要查找的xml標簽路徑,2上下文節點對象也就是XMLDOM對象,3命名空間求解器(通常是null),4返回結果類型,5保存結果的XPathResult對象(通常是null)。 var result = eva.evaluate('root/user', xmldom , null,XPathResult.FIRST_ORDERED_NODE_TYPE, null); alert(result); //返回單一節點集合//首先,我們需要跨瀏覽器獲取XML DOM function getXMLDOM(xmlStr) { //自定義跨瀏覽器創建xml DOM對象,接收一個參數xml字符串var xmlDom = null; //初始化一個對象if (typeof window.DOMParser != 'undefined') { //判斷DOMParser類型不等于undefined說明支持//創建DOMParser對象,并且創建xml DOM對象xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');//獲取錯誤信息的parsererror標簽var errors = xmlDom.getElementsByTagName('parsererror');//判斷錯誤信息標簽返回集合長度大于0,說明xml有錯誤if (errors.length > 0) {//創建一個錯誤對象,獲取到第一個錯誤標簽,并且獲取到他的文本內容throw new Error('XML解析錯誤:' + errors[0].firstChild.nodeValue);}//如果不支持DOMParser類型,嘗試IE的方法} else if (typeof window.ActiveXObject != 'undefined') { //判斷ActiveXObject類型不等于undefined說明支持var version = [ //創建一個數組,元素分別為3個xml版本'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i++) { //根據數組的長度循環次數try {//嘗試著執行每次循環到的xml版本,創建xml對象xmlDom = new ActiveXObject(version[i]);} catch (e) { //如果出錯跳過執行第二次循環//跳過 }}xmlDom.loadXML(xmlStr); //載入xml字符串if (xmlDom.parseError != 0) { //判斷載入xml錯誤返回代碼,如果不等于0說明xml有錯//創建一個錯誤對象,返回錯誤的解釋信息throw new Error('XML解析錯誤:' + xmlDom.parseError.reason);}} else { //如果 上面兩種方式都不支持//創建一個錯誤對象,拋出您所使用的系統或瀏覽器不支持XML DOM!throw new Error('您所使用的系統或瀏覽器不支持XML DOM!');}return xmlDom; //最后返回創建的xmlDOM對象 }//其次,我們還必須跨瀏覽器序列化XML function serializeXML(xmlDom) { //序列化xml函數,接收xmlDOM對象對象var xml = ''; //初始化一個變量等于空字符串if (typeof XMLSerializer != 'undefined') { //判斷XMLSerializer類型,不等于undefined,說明支持序列化//給xml重新賦值,創建XMLSerializer對象,并且使用serializeToString方法序列化xml = (new XMLSerializer()).serializeToString(xmlDom);//如果不支持XMLSerializer類型} else if (typeof xmlDom.xml != 'undefined') { //判斷IE方式xmlDOM對象下的xml屬性是否等于undefined,不等于說明支持//給xml重新賦值,序列化xmlxml = xmlDom.xml;} else { //如果上面兩種都不支持//創建一個錯誤對象,拋出無法解析XML!錯誤信息throw new Error('無法解析XML!');}return xml; //最后返回序列化 }使用上下文節點對象(xmlDom)創建XPathResult對象,就是直接在XMLDOM對象執行evaluate()方法
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //創建XML DOM對象,接收xml字符串//使用上下文節點對象(xmlDom)創建XPathResult var result = xmldom.evaluate('root/user', xmldom, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null); alert(result); //返回單一節點集合//首先,我們需要跨瀏覽器獲取XML DOM function getXMLDOM(xmlStr) { //自定義跨瀏覽器創建xml DOM對象,接收一個參數xml字符串var xmlDom = null; //初始化一個對象if (typeof window.DOMParser != 'undefined') { //判斷DOMParser類型不等于undefined說明支持//創建DOMParser對象,并且創建xml DOM對象xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');//獲取錯誤信息的parsererror標簽var errors = xmlDom.getElementsByTagName('parsererror');//判斷錯誤信息標簽返回集合長度大于0,說明xml有錯誤if (errors.length > 0) {//創建一個錯誤對象,獲取到第一個錯誤標簽,并且獲取到他的文本內容throw new Error('XML解析錯誤:' + errors[0].firstChild.nodeValue);}//如果不支持DOMParser類型,嘗試IE的方法} else if (typeof window.ActiveXObject != 'undefined') { //判斷ActiveXObject類型不等于undefined說明支持var version = [ //創建一個數組,元素分別為3個xml版本'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i++) { //根據數組的長度循環次數try {//嘗試著執行每次循環到的xml版本,創建xml對象xmlDom = new ActiveXObject(version[i]);} catch (e) { //如果出錯跳過執行第二次循環//跳過 }}xmlDom.loadXML(xmlStr); //載入xml字符串if (xmlDom.parseError != 0) { //判斷載入xml錯誤返回代碼,如果不等于0說明xml有錯//創建一個錯誤對象,返回錯誤的解釋信息throw new Error('XML解析錯誤:' + xmlDom.parseError.reason);}} else { //如果 上面兩種方式都不支持//創建一個錯誤對象,拋出您所使用的系統或瀏覽器不支持XML DOM!throw new Error('您所使用的系統或瀏覽器不支持XML DOM!');}return xmlDom; //最后返回創建的xmlDOM對象 }//其次,我們還必須跨瀏覽器序列化XML function serializeXML(xmlDom) { //序列化xml函數,接收xmlDOM對象對象var xml = ''; //初始化一個變量等于空字符串if (typeof XMLSerializer != 'undefined') { //判斷XMLSerializer類型,不等于undefined,說明支持序列化//給xml重新賦值,創建XMLSerializer對象,并且使用serializeToString方法序列化xml = (new XMLSerializer()).serializeToString(xmlDom);//如果不支持XMLSerializer類型} else if (typeof xmlDom.xml != 'undefined') { //判斷IE方式xmlDOM對象下的xml屬性是否等于undefined,不等于說明支持//給xml重新賦值,序列化xmlxml = xmlDom.xml;} else { //如果上面兩種都不支持//創建一個錯誤對象,拋出無法解析XML!錯誤信息throw new Error('無法解析XML!');}return xml; //最后返回序列化 }相對而言,第二種簡單方便一點,但evaluate方法有五個屬性:1.XPath路徑、2.上下文節點對象、3.命名空間求解器(通常是null)、4.返回結果類型、5保存結果的XPathResult對象(通常是null)。
?
獲取xml節點
1.獲取一個單一節點
singleNodeValue屬性,得到XPathResult對象里的單一節點對象,獲取返回類型XPathResult.FIRST_ORDERED_NODE_TYPE的節點對象
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //創建XML DOM對象,接收xml字符串var result = xmldom.evaluate('root/user', xmldom, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (result !== null) {//singleNodeValue屬性,得到XPathResult對象里的節點對象alert(result.singleNodeValue.tagName); //打印出節點的標簽名稱 }//首先,我們需要跨瀏覽器獲取XML DOM function getXMLDOM(xmlStr) { //自定義跨瀏覽器創建xml DOM對象,接收一個參數xml字符串var xmlDom = null; //初始化一個對象if (typeof window.DOMParser != 'undefined') { //判斷DOMParser類型不等于undefined說明支持//創建DOMParser對象,并且創建xml DOM對象xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');//獲取錯誤信息的parsererror標簽var errors = xmlDom.getElementsByTagName('parsererror');//判斷錯誤信息標簽返回集合長度大于0,說明xml有錯誤if (errors.length > 0) {//創建一個錯誤對象,獲取到第一個錯誤標簽,并且獲取到他的文本內容throw new Error('XML解析錯誤:' + errors[0].firstChild.nodeValue);}//如果不支持DOMParser類型,嘗試IE的方法} else if (typeof window.ActiveXObject != 'undefined') { //判斷ActiveXObject類型不等于undefined說明支持var version = [ //創建一個數組,元素分別為3個xml版本'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i++) { //根據數組的長度循環次數try {//嘗試著執行每次循環到的xml版本,創建xml對象xmlDom = new ActiveXObject(version[i]);} catch (e) { //如果出錯跳過執行第二次循環//跳過 }}xmlDom.loadXML(xmlStr); //載入xml字符串if (xmlDom.parseError != 0) { //判斷載入xml錯誤返回代碼,如果不等于0說明xml有錯//創建一個錯誤對象,返回錯誤的解釋信息throw new Error('XML解析錯誤:' + xmlDom.parseError.reason);}} else { //如果 上面兩種方式都不支持//創建一個錯誤對象,拋出您所使用的系統或瀏覽器不支持XML DOM!throw new Error('您所使用的系統或瀏覽器不支持XML DOM!');}return xmlDom; //最后返回創建的xmlDOM對象 }//其次,我們還必須跨瀏覽器序列化XML function serializeXML(xmlDom) { //序列化xml函數,接收xmlDOM對象對象var xml = ''; //初始化一個變量等于空字符串if (typeof XMLSerializer != 'undefined') { //判斷XMLSerializer類型,不等于undefined,說明支持序列化//給xml重新賦值,創建XMLSerializer對象,并且使用serializeToString方法序列化xml = (new XMLSerializer()).serializeToString(xmlDom);//如果不支持XMLSerializer類型} else if (typeof xmlDom.xml != 'undefined') { //判斷IE方式xmlDOM對象下的xml屬性是否等于undefined,不等于說明支持//給xml重新賦值,序列化xmlxml = xmlDom.xml;} else { //如果上面兩種都不支持//創建一個錯誤對象,拋出無法解析XML!錯誤信息throw new Error('無法解析XML!');}return xml; //最后返回序列化 }2.獲取節點集合
?iterateNext()方法,得到XPathResult對象里的集合節點對象,獲取返回類型XPathResult.ORDERED_NODE_ITERATOR_TYPE的節點對象
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //創建XML DOM對象,接收xml字符串//使用上下文節點對象(xmlDom)創建XPathResult,返回類型為xml標簽集合 var result = xmldom.evaluate('root/user', xmldom, null,XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); if (result !== null) { //判斷集合不為空var nodes = []; //創建空數組var node = result.iterateNext(); //獲取到集合里的一個標簽對象while (node !== null) { //判斷獲取集合里的一個標簽對象不為空,循環這個節點集合nodes.push(node); //將循環到的節點添加到初始化數組node = result.iterateNext(); //再次取集合里的一個標簽對象,進行迭代 } }alert(serializeXML(nodes[0])); //序列化打印第一個節點 alert(serializeXML(nodes[1])); //序列化打印第二個節點//首先,我們需要跨瀏覽器獲取XML DOM function getXMLDOM(xmlStr) { //自定義跨瀏覽器創建xml DOM對象,接收一個參數xml字符串var xmlDom = null; //初始化一個對象if (typeof window.DOMParser != 'undefined') { //判斷DOMParser類型不等于undefined說明支持//創建DOMParser對象,并且創建xml DOM對象xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');//獲取錯誤信息的parsererror標簽var errors = xmlDom.getElementsByTagName('parsererror');//判斷錯誤信息標簽返回集合長度大于0,說明xml有錯誤if (errors.length > 0) {//創建一個錯誤對象,獲取到第一個錯誤標簽,并且獲取到他的文本內容throw new Error('XML解析錯誤:' + errors[0].firstChild.nodeValue);}//如果不支持DOMParser類型,嘗試IE的方法} else if (typeof window.ActiveXObject != 'undefined') { //判斷ActiveXObject類型不等于undefined說明支持var version = [ //創建一個數組,元素分別為3個xml版本'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i++) { //根據數組的長度循環次數try {//嘗試著執行每次循環到的xml版本,創建xml對象xmlDom = new ActiveXObject(version[i]);} catch (e) { //如果出錯跳過執行第二次循環//跳過 }}xmlDom.loadXML(xmlStr); //載入xml字符串if (xmlDom.parseError != 0) { //判斷載入xml錯誤返回代碼,如果不等于0說明xml有錯//創建一個錯誤對象,返回錯誤的解釋信息throw new Error('XML解析錯誤:' + xmlDom.parseError.reason);}} else { //如果 上面兩種方式都不支持//創建一個錯誤對象,拋出您所使用的系統或瀏覽器不支持XML DOM!throw new Error('您所使用的系統或瀏覽器不支持XML DOM!');}return xmlDom; //最后返回創建的xmlDOM對象 }//其次,我們還必須跨瀏覽器序列化XML function serializeXML(xmlDom) { //序列化xml函數,接收xmlDOM對象對象var xml = ''; //初始化一個變量等于空字符串if (typeof XMLSerializer != 'undefined') { //判斷XMLSerializer類型,不等于undefined,說明支持序列化//給xml重新賦值,創建XMLSerializer對象,并且使用serializeToString方法序列化xml = (new XMLSerializer()).serializeToString(xmlDom);//如果不支持XMLSerializer類型} else if (typeof xmlDom.xml != 'undefined') { //判斷IE方式xmlDOM對象下的xml屬性是否等于undefined,不等于說明支持//給xml重新賦值,序列化xmlxml = xmlDom.xml;} else { //如果上面兩種都不支持//創建一個錯誤對象,拋出無法解析XML!錯誤信息throw new Error('無法解析XML!');}return xml; //最后返回序列化 }PS:節點集合的獲取方式,是通過迭代器遍歷而來的,我們保存到數據中就模擬出IE相似的風格。
?
三.XPath跨瀏覽器兼容
如果要做W3C和IE的跨瀏覽器兼容,我們要思考幾個問題:1.如果傳遞一個節點的下標,IE是從0開始計算,W3C從1開始計算,可以通過傳遞獲取下標進行增1減1的操作來進行。2.獨有的功能放棄,為了保證跨瀏覽器。3.只獲取單一節點和節點列表即可,基本可以完成所有的操作。
?跨瀏覽器獲取單一節點
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //創建XML DOM對象,接收xml字符串 var jied = selectSingleNode(xmldom,'root/user'); //執行跨瀏覽器獲取單一節點函數 alert(serializeXML(jied)); //序列化節點標簽//跨瀏覽器獲取單一節點,返回單一節點對象 function selectSingleNode(xmlDom, xpath) { //加收兩個參數,參數1XML DOM對象,參數二要查找的標簽路徑var node = null; //初始化if (typeof xmlDom.evaluate != 'undefined') { //判斷XML DOM對象下的evaluate方法不等于undefined,說明支持,就用ie9以下的方式var patten = /\[(\d+)\]/g; //正則var flag = xpath.match(patten); //返回正則匹配到的字符串var num = 0; //初始化if (flag !== null) {num = parseInt(RegExp.$1) + 1;xpath = xpath.replace(patten, '[' + num + ']');}var result = xmlDom.evaluate(xpath, xmlDom, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null);if (result !== null) {node = result.singleNodeValue;}} else if (typeof xmlDom.selectSingleNode != 'undefined') { //w3c方式node = xmlDom.selectSingleNode(xpath);}return node; }//首先,我們需要跨瀏覽器獲取XML DOM function getXMLDOM(xmlStr) { //自定義跨瀏覽器創建xml DOM對象,接收一個參數xml字符串var xmlDom = null; //初始化一個對象if (typeof window.DOMParser != 'undefined') { //判斷DOMParser類型不等于undefined說明支持//創建DOMParser對象,并且創建xml DOM對象xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');//獲取錯誤信息的parsererror標簽var errors = xmlDom.getElementsByTagName('parsererror');//判斷錯誤信息標簽返回集合長度大于0,說明xml有錯誤if (errors.length > 0) {//創建一個錯誤對象,獲取到第一個錯誤標簽,并且獲取到他的文本內容throw new Error('XML解析錯誤:' + errors[0].firstChild.nodeValue);}//如果不支持DOMParser類型,嘗試IE的方法} else if (typeof window.ActiveXObject != 'undefined') { //判斷ActiveXObject類型不等于undefined說明支持var version = [ //創建一個數組,元素分別為3個xml版本'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i++) { //根據數組的長度循環次數try {//嘗試著執行每次循環到的xml版本,創建xml對象xmlDom = new ActiveXObject(version[i]);} catch (e) { //如果出錯跳過執行第二次循環//跳過 }}xmlDom.loadXML(xmlStr); //載入xml字符串if (xmlDom.parseError != 0) { //判斷載入xml錯誤返回代碼,如果不等于0說明xml有錯//創建一個錯誤對象,返回錯誤的解釋信息throw new Error('XML解析錯誤:' + xmlDom.parseError.reason);}} else { //如果 上面兩種方式都不支持//創建一個錯誤對象,拋出您所使用的系統或瀏覽器不支持XML DOM!throw new Error('您所使用的系統或瀏覽器不支持XML DOM!');}return xmlDom; //最后返回創建的xmlDOM對象 }//其次,我們還必須跨瀏覽器序列化XML function serializeXML(xmlDom) { //序列化xml函數,接收xmlDOM對象對象var xml = ''; //初始化一個變量等于空字符串if (typeof XMLSerializer != 'undefined') { //判斷XMLSerializer類型,不等于undefined,說明支持序列化//給xml重新賦值,創建XMLSerializer對象,并且使用serializeToString方法序列化xml = (new XMLSerializer()).serializeToString(xmlDom);//如果不支持XMLSerializer類型} else if (typeof xmlDom.xml != 'undefined') { //判斷IE方式xmlDOM對象下的xml屬性是否等于undefined,不等于說明支持//給xml重新賦值,序列化xmlxml = xmlDom.xml;} else { //如果上面兩種都不支持//創建一個錯誤對象,拋出無法解析XML!錯誤信息throw new Error('無法解析XML!');}return xml; //最后返回序列化 }跨瀏覽器獲取節點集合
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //創建XML DOM對象,接收xml字符串 var jied = selectNodes(xmldom,'root/user'); //執行跨瀏覽器獲取集合節點函數 alert(serializeXML(jied[0])); //序列化節點標簽//跨瀏覽器獲取節點集合,返回節點集合 function selectNodes(xmlDom, xpath) { //接收兩個參數,參數1XML DOM對象,參數2要查找的節點標簽路徑var nodes = [];if (typeof xmlDom.evaluate != 'undefined') {var patten = /\[(\d+)\]/g;var flag = xpath.match(patten);var num = 0;if (flag !== null) {num = parseInt(RegExp.$1) + 1;xpath = xpath.replace(patten, '[' + num + ']');}var node = null;var result = xmlDom.evaluate('root/user', xmlDom, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);if (result !== null) {while ((node = result.iterateNext()) !== null) {nodes.push(node);}}} else if (typeof xmlDom.selectNodes != 'undefined') {nodes = xmlDom.selectNodes(xpath);}return nodes; }//首先,我們需要跨瀏覽器獲取XML DOM function getXMLDOM(xmlStr) { //自定義跨瀏覽器創建xml DOM對象,接收一個參數xml字符串var xmlDom = null; //初始化一個對象if (typeof window.DOMParser != 'undefined') { //判斷DOMParser類型不等于undefined說明支持//創建DOMParser對象,并且創建xml DOM對象xmlDom = (new DOMParser()).parseFromString(xmlStr, 'text/xml');//獲取錯誤信息的parsererror標簽var errors = xmlDom.getElementsByTagName('parsererror');//判斷錯誤信息標簽返回集合長度大于0,說明xml有錯誤if (errors.length > 0) {//創建一個錯誤對象,獲取到第一個錯誤標簽,并且獲取到他的文本內容throw new Error('XML解析錯誤:' + errors[0].firstChild.nodeValue);}//如果不支持DOMParser類型,嘗試IE的方法} else if (typeof window.ActiveXObject != 'undefined') { //判斷ActiveXObject類型不等于undefined說明支持var version = [ //創建一個數組,元素分別為3個xml版本'MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','MSXML2.DOMDocument'];for (var i = 0; i < version.length; i++) { //根據數組的長度循環次數try {//嘗試著執行每次循環到的xml版本,創建xml對象xmlDom = new ActiveXObject(version[i]);} catch (e) { //如果出錯跳過執行第二次循環//跳過 }}xmlDom.loadXML(xmlStr); //載入xml字符串if (xmlDom.parseError != 0) { //判斷載入xml錯誤返回代碼,如果不等于0說明xml有錯//創建一個錯誤對象,返回錯誤的解釋信息throw new Error('XML解析錯誤:' + xmlDom.parseError.reason);}} else { //如果 上面兩種方式都不支持//創建一個錯誤對象,拋出您所使用的系統或瀏覽器不支持XML DOM!throw new Error('您所使用的系統或瀏覽器不支持XML DOM!');}return xmlDom; //最后返回創建的xmlDOM對象 }//其次,我們還必須跨瀏覽器序列化XML function serializeXML(xmlDom) { //序列化xml函數,接收xmlDOM對象對象var xml = ''; //初始化一個變量等于空字符串if (typeof XMLSerializer != 'undefined') { //判斷XMLSerializer類型,不等于undefined,說明支持序列化//給xml重新賦值,創建XMLSerializer對象,并且使用serializeToString方法序列化xml = (new XMLSerializer()).serializeToString(xmlDom);//如果不支持XMLSerializer類型} else if (typeof xmlDom.xml != 'undefined') { //判斷IE方式xmlDOM對象下的xml屬性是否等于undefined,不等于說明支持//給xml重新賦值,序列化xmlxml = xmlDom.xml;} else { //如果上面兩種都不支持//創建一個錯誤對象,拋出無法解析XML!錯誤信息throw new Error('無法解析XML!');}return xml; //最后返回序列化 }PS:在傳遞xpath路徑時,沒有做驗證判斷是否合法,有興趣的同學可以自行完成。在XML還有一個重要章節是XSLT和EX4,由于在使用頻率的緣故,我們暫且擱置。
轉載于:https://www.cnblogs.com/adc8868/p/6216078.html
總結
以上是生活随笔為你收集整理的第一百二十六节,JavaScript,XPath操作xml节点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联合体(union)和结构体(struc
- 下一篇: 2013Esri中国用户大会,show应