Javascript—XPATH技術解析XML

XML可擴展標記語言,作為傳輸和存儲數據的載體,在web開發中應用很廣泛。在我們需要將XML數據傳遞給前端時,需要用javascript解析才能使用,所以,使用javascript解析XML也是很普遍的。

通過javascript解析XML,我們可以使用DOM這個強大的工具(針對HTML文檔、XML等文檔的一套API),也就是通過getElementById或者getElementsByTagName這些方法解析XML。

那它們在解析XML時是否合適,我們考慮下下面的幾個問題:

首先XML中每個元素節點不一定有id屬性;其次XML中的兩個元素節點可能有相同的id屬性;這樣使用getElementById就不能保證找到我們需要的唯一節點瞭。而getElementsByTagName一次獲取的節點太多,在進行遍歷獲取數據,比較麻煩。

就XML而言,對比JSON,XML文件龐大,格式復雜,在通過DOM解析顯然需要花費更過的資源和時間,用戶體驗肯定不好。

有沒有更好點的方法呢?

XPATH技術—解決問題的良藥

XPATH是什麼?全稱是XML
Path Language(XML路徑語言),適用於確定XML文檔中某節點位置的語言。

我們可以把它當作類似於SQL一樣的查詢語言,通過給出XPATH路徑信息(就像SQL命令一樣)就可以從XML中查找出符合條件的節點(就像從數據庫中返回需要的數據一樣)。

Java中的DOM4j開源包中有selectSingleNode和selectNodes這樣兩個方法可以根據XPATH表達式來獲取一個或多個節點。

在IE6.0及以後版本中我們可以使用同樣的方式來訪問任意深度的XML數據,這給XML數據的解析操作帶來瞭便利。

但是在firefox等瀏覽器中,則是使用瞭w3c標準的XPATH處理方式,沒有IE這麼簡單的方式,firefox中需要建立相應的操作對象和計算方法,才能返回對應的節點。

封裝方法,創建在不同瀏覽器中都可進行XPATH操作的封裝方法

    //根據指定的XPATH表達式查找滿足條件的所有節點
    //@param xmldoc 執行查找的節點
    //@param sXpath xpath的表達式
    function selectNodes(xmldoc,sXpath){  
      
        if(window.ActiveXObject){       
            //IE瀏覽器     
            return xmldoc.selectNodes(sXpath);        
        }else if(window.XPathEvaluator){      
            //FireFox類瀏覽器       
            var xpathObj=new XPathEvaluator();  

            if(xpathObj){  
                     var result=xpathObj.evaluate(sXpath,xmldoc,null,XPathResult.ORDERED_NODE_ITEARTOR_TYPE,null);        
                var nodes=new Array();        
                var node;        
                while((node = result.iterateNext())!=null) {        
                    nodes.push(node);       
                }        
               return nodes;  
      
            }else{  
      
                return null;                              
            }  
      
        }else{        
            return null;        
        }        
    }  

    //根據指定的XPATH表達式查找滿足條件的第一個節點
    //@param xmldoc 執行查找的節點
    //@param sXpath xpath的表達式
    function selectSingleNode(xmldoc,sXpath){  
        if(window.ActiveXObject){       
            //IE瀏覽器        
            return xmldoc.selectSingleNode(sXpath);        
        }else if(window.XPathEvaluator){        
            //FireFox類瀏覽器        
            var xpathObj=new XPathEvaluator();        
            if(xpathObj){        
                var result=xpathObj.evaluate(sXpath,xmldoc,null,XPathResult.ORDERED_NODE_ITEARTOR_TYPE,null);                              
                return result.singleNodeValue;        
            }else{        
                return null;                               
            }        
        }else{        
            return null;        
        }        
    }  

註:

evaluate()方法返回的是一個節點列表,得到節點列表後iterateNext()方法來遍歷這個列表中的所有節點。而ORDERED_NODE_ITERATOR_TYPE就是節點的列表,按照文檔中節點的屬性排列。

實例—通過XPATH表達式獲取XML數據

XML



    
        wang
        AJAX Professional
        35
    
    
        lee
        AJAX In Action
        65
    
    
        zhu
        AJAX For Dummies
        40
    
    123

通過調用selectNodes()函數來獲取不同參數的值

下面通過六個需求來進行說明

      <script type="text/javascript">
            function testxpath(){
                var rootElement = loadXML(true,"XPATH.xml");
                removeBlank(rootElement);
             
                //需求1,獲取元素節點
                //查找所有的author元素節點
                //關鍵就是如何表式元素節點在DOM樹中的路徑
                // 絕對路徑 /books/book/author
                // 相對路徑 book/author
                // 全文檔搜索法 //author , //book/author
                var author1 = selectNodes(rootElement,"/books/book/author");
                var author2 = selectNodes(rootElement,"book/author");
                var author2 = selectNodes(rootElement,"//author");
                var author2 = selectNodes(rootElement,"//book/author");
                
                //需求2,獲取屬性節點
                //關鍵是先找到包含屬性節點的元素節點
                var isdn1 = selectNodes(rootElement,"/books/book/@isdn");
                var isdn2 = selectNodes(rootElement,"book/@isdn");
                var isdn3 = selectNodes(rootElement,"//book/@isdn");
                var isdn4 = selectNodes(rootElement,"//books/@isdn");
                
                //需求3,獲取文本節點
                //關鍵是找到包含文本節點的那個元素節點
                var text1 = selectNodes(rootElement,"/books/book/name/text()");
                var text2 = selectNodes(rootElement,"book/name/text()");
                var text3 = selectNodes(rootElement,"//book/name/text()");
                var text4 = selectNodes(rootElement,"//name/text()");
                
                //需求4,有條件的查找元素節點
                //需要先找到元素節點,然後再增加條件表達式,[條件]
                var book1 = selectNodes(rootElement,"/books/book[@isdn]");
                var book2 = selectNodes(rootElement,"book[@isdn]");
                var book3 = selectNodes(rootElement,"//book[@isdn]");
                
                //需求5,多個添加與關系的查找元素節點
                //需要首先找到元素節點,然後每一個查詢條件寫在一個中括號中
                var bookA1 = selectNodes(rootElement,"/books/book[@isdn='0002'][price>35]");
                var bookA2 = selectNodes(rootElement,"book[@isdn='0002'][price>35]");
                var bookA3 = selectNodes(rootElement,"//book[@isdn='0002'][price>35]");
                
                //需求6,‘|’或關系查找
                var bookA3 = selectNodes(rootElement,"//book[@isdn='0002']| /books/book[price>35]");
                
                alert("");
            }
        </script>

XPath是對專門對XML操作的語言,通過XPath語言,可以很方便的找到你想要的那個節點,代碼方便,而且效率。

相比JSON,XML有優點也有缺點,各有優勢,進一步研究請關註我的博客。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *