第一百二十六節,JavaScript,XPath操做xml節點

第一百二十六節,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,因爲在使用頻率的緣故,咱們暫且擱置。

相關文章
相關標籤/搜索