第一百二十六節,JavaScript,XPath操做xml節點node
學習要點:數組
1.IE中的XPath瀏覽器
2.W3C中的XPathdom
3.XPath跨瀏覽器兼容函數
XPath是一種節點查找手段,對比以前使用標準DOM去查找XML中的節點方式,大大下降了查找難度,方便開發者使用。可是,DOM3級之前的標準並無就XPath作出規範;直到DOM3在首次推薦到標準規範行列。大部分瀏覽器實現了這個標準,IE則以本身的方式實現了XPath。學習
一.IE中的XPathlua
在IE8及以前的瀏覽器,XPath是採用內置基於ActiveX的XML DOM文檔對象實現的。在每個節點上提供了兩個方法:selectSingleNode()和selectNodes()。spa
selectSingleNode()方法接受一個XPath模式(也就是查找路徑),找到匹配的第一個節點並將它返回,沒有則返回null。指針
selectSingleNode()方法,查找xml節點,查找單一節點若是有相同的節點只返回第一個節點,有參參數是要查找的節點路徑,此方法只支持IE而且是IE9如下
使用方式
XML DOM對象.selectSingleNode('要查找的節點路徑')code
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //建立XML DOM對象,接收xml字符串 //經過XML DOM對象查找xml標籤節點 var chzhao = xmldom.selectSingleNode('root/user'); //selectSingleNode()方法,查找xml節點,有參參數是要查找的節點路徑,此方法只支持IE而且是IE9如下 alert(serializeXML(chzhao)); //執行序列化函數,序列化查找到的節點 alert(chzhao.tagName); //打印查找到的元素標籤名稱 alert(chzhao.firstChild.nodeValue); //打印查找到的元素文本內容 //首先,咱們須要跨瀏覽器獲取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從新賦值,序列化xml xml = xmlDom.xml; } else { //若是上面兩種都不支持 //建立一個錯誤對象,拋出沒法解析XML!錯誤信息 throw new Error('沒法解析XML!'); } return xml; //最後返回序列化 }
上下文節點
上下文節點:咱們經過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路徑,省去了root var user = xmlDom.documentElement.selectSingleNode('user'); alert(user.tagName); //user
經過xmlDom,而且使用user路徑,省去了root
//經過xmlDom,而且使用user路徑,省去了root var 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('要查找的節點路徑')
var xml = '<root><user id="5">Lee</user><user id="6">Koko</user></root>'; //定義xml字符串 var xmldom = getXMLDOM(xml); //建立XML DOM對象,接收xml字符串 //經過XML DOM對象查找xml標籤節點 var chzhao = xmldom.selectNodes('root/user'); //selectNodes()方法,查找xml節點,返回相同名稱的節點集合,有參參數是要查找的節點路徑,此方法只支持IE而且是IE9如下 alert(chzhao.length); //查看節點集合長度 alert(serializeXML(chzhao[0])); //經過索引,執行序列化函數,序列化查找到的節點 alert(chzhao[0].tagName); //經過索引打印查找到的元素標籤名稱 alert(chzhao[0].firstChild.nodeValue); //經過索引打印查找到的元素文本內容 //首先,咱們須要跨瀏覽器獲取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從新賦值,序列化xml xml = xmlDom.xml; } else { //若是上面兩種都不支持 //建立一個錯誤對象,拋出沒法解析XML!錯誤信息 throw new Error('沒法解析XML!'); } return xml; //最後返回序列化 }
二.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從新賦值,序列化xml xml = 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從新賦值,序列化xml xml = 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從新賦值,序列化xml xml = 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從新賦值,序列化xml xml = 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從新賦值,序列化xml xml = 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從新賦值,序列化xml xml = xmlDom.xml; } else { //若是上面兩種都不支持 //建立一個錯誤對象,拋出沒法解析XML!錯誤信息 throw new Error('沒法解析XML!'); } return xml; //最後返回序列化 }
PS:在傳遞xpath路徑時,沒有作驗證判斷是否合法,有興趣的同窗能夠自行完成。在XML還有一個重要章節是XSLT和EX4,因爲在使用頻率的緣故,咱們暫且擱置。