XPath <第四篇>


  .Net框架下的System.Xml.XPath命名空間提供了一系列的類,允許你應用XPath數據模式查詢和展示XML文檔數據。

一、XPath介紹

  XPath有七種類型的節點:元素、屬性、文本、命名空間、處理指令、注釋、根節點。

二、XPath語法

  XPath使用路徑表達式來選取XML文檔中的節點或節點集。

  1、常用的路徑表達式:

表達式 解釋
nodename 選取節點下的所有子節點
/ 選取根節點
// 選取文檔中所有符合條件的節點,不管該節點位於何處
. 選取當前節點
.. 選取當前節點的父節點
@ 選取屬性

 

  先貼一個XML文檔,以此作為示例的試驗文檔:

<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
  <book>
    <title lang="en">三國演義</title>
    <author>羅貫中</author>
    <year>2005</year>
    <price>38.5</price>
  </book>
  <book>
    <title lang="eng">西游記</title>
    <author>吳承恩</author>
    <year>2004</year>
    <price>37.5</price>
  </book>
</bookstore>

  示例代碼:

        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();    //創建文檔
            doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml");     //加載xml文件

            XmlNode node1 = doc.SelectSingleNode("/");          //選中根節點
            Console.WriteLine(node1.LocalName);  //輸出#document

            XmlNode node2 = doc.SelectSingleNode("bookstore");  //選中bookstore元素
            Console.WriteLine(node2.Name);  //輸出 bookstore

            XmlNode node3 = doc.SelectSingleNode("/bookstore"); //選中根節點下的bookstore元素
            Console.WriteLine(node3.Name);  //輸出    bookstore

            XmlNodeList nodelist1 = doc.SelectNodes("//id");    //選中所有符合條件的id元素,不管它的位置如何
            foreach (XmlNode node in nodelist1)
            {
                Console.WriteLine(node.InnerText);  //輸出 1 2
            }

            XmlNodeList nodelist2 = doc.SelectNodes("bookstore/book/title");    //讀取bookstore下的所有book元素下的所有title元素
            foreach (XmlNode node in nodelist2)
            {
                Console.WriteLine(node.InnerText);  //輸出 三國演義 西游記
            }

            XmlNode node4 = doc.SelectSingleNode("/bookstore/book[1]/title[1]/.");  //獲取第一個title的當前節點
            Console.WriteLine(node4.Name);  //輸出title

            XmlNode node5 = doc.SelectSingleNode("/bookstore/book[1]/title[1]/.."); //獲取第一個title的父節點
            Console.WriteLine(node5.Name);  //輸出book

            Console.ReadKey();
        }

  2、通配符

通配符 說明
* 匹配任意的節點元素
@* 匹配任意的節點屬性
node() 匹配任意種類的節點
text() 匹配節點的文本內容

  示例代碼:

        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();    //創建文檔
            doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml");     //加載xml文件

            XmlNodeList nodelist1 = doc.SelectNodes("/bookstore/*");  //匹配bookstore下的直接子元素
            foreach (XmlNode node in nodelist1)
            {
                Console.WriteLine(node.Name);   //輸出 book book 兩個book才是直接子元素
            }

            XmlNodeList nodelist2 = doc.SelectNodes("//title[@*]"); //匹配所有含有任意屬性的title元素
            foreach (XmlNode node in nodelist2)
            {
                Console.WriteLine(node.Name);   //輸出 title title 兩個title含有屬性
            }

            XmlNodeList nodelist3 = doc.SelectNodes("//*"); //匹配所有含有任意屬性的title元素
            foreach (XmlNode node in nodelist3)
            {
                Console.WriteLine(node.Name);   //輸出 所有的元素名 從上至下
            }

            XmlNodeList nodelist4 = doc.SelectNodes("//title|//author");    //匹配所有的title和author元素
            foreach (XmlNode node in nodelist4)
            {
                Console.WriteLine(node.InnerText);   //輸出 三國演義 羅貫中 西游記 吳承恩
            }

            Console.ReadKey();
        }

  3、軸

    XPath軸可定義相對於當前節點的節點集:

軸名稱 結果
ancestor 選取當前節點的所有先輩(父,祖父等)不包括自己
ancestor-or-self 選取當前節點的所有先輩,以及自己
attribute 選取當前節點的所有屬性
child 選取當前節點的所有子元素
descendant 選取當前節點的所有后代元素(子、孫等)不包括自己
descendant-or-self 選取當前節點的所有后代元素,以及自己
following 選取文檔中當前節點的結束標簽之后的所有節點
namespace 選取當前節點的所有命名空間節點
parent 選取當前節點的父節點
preceding 選取文檔中當前節點的開始標簽之前的所有節點
preceding-sibling 選取當前節點之前的所有統計節點
self 選取當前節點

 

   與軸有關的兩個重要概念:

  1. 位置;
  2. 步;

   位置路徑可以是絕對的,也可以是相對的。

   絕對路徑表達式:

 /step/step/...

   相對路徑表達式:

step/step/...

   而步的定義包括:

  • 軸:定義所選節點與當前節點之間的樹關系;
  • 節點測試:識別某個軸內部的節點;
  • 另個或者多個謂詞:更深入地提煉所選的節點集。

   步的語法:

   軸名稱::節點測試[謂詞]

   代碼示例:

        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();    //創建文檔
            doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml");     //加載xml文件

            XmlNode node1 = doc.SelectSingleNode("/bookstore/book[1]");

            XmlNode node2 = node1.SelectSingleNode("ancestor::*"); //選取當前節點的祖先節點,選擇單個(SelectSingleNode)就是直接父元素
            Console.WriteLine(node2.Name);  //輸出 bookstore

            XmlNodeList nodelist1 = node1.SelectNodes("ancestor-or-self::*");   //選取當前節點的所有先輩元素
            foreach (XmlNode node in nodelist1)
            {
                Console.WriteLine(node.Name);   //輸出 bookstore book     book是self bookstore是ancestor
            }

            XmlNode node3 = node1.SelectSingleNode("child::title");     //選取當前節點的子元素叫title的節點
            Console.WriteLine(node3.InnerText);         //輸出 三國演義

            XmlNodeList nodelist2 = node1.SelectNodes("descendant::*");
            foreach (XmlNode node in nodelist2)
            {
                Console.WriteLine(node.Name);   //輸出 id title author year price
            }

            XmlNodeList nodelist3 = node1.SelectNodes("descendant-or-self::*");     //獲取所有的子節點以及自身
            foreach (XmlNode node in nodelist3)
            {
                Console.WriteLine(node.Name);   //輸出 book id title author year price    其中book是self
            }

            XmlNodeList nodelist4 = node1.SelectNodes("following::*");  //獲取第一個book標簽結束后的所有節點
            foreach (XmlNode node in nodelist4)
            {
                Console.WriteLine(node.Name);   //輸出 book id title author year price
            }

            XmlNode node4 = node1.SelectSingleNode("parent::*");    //獲取當前的節點的父節點
            Console.WriteLine(node4.Name);      //輸出 bookstore

            Console.WriteLine("----------------");

            XmlNode node5 = doc.SelectSingleNode("/bookstore/book[2]/title[1]");    //選取第二個book的第一個title節點
            XmlNodeList nodelist5 = node5.SelectNodes("preceding::*"); //獲取當前節點(第二個book的第一個title)開始之前的所有節點
            foreach (XmlNode node in nodelist5)
            {
                Console.WriteLine(node.Name);   //輸出 book id title author year price id
            }

            XmlNodeList nodelist6 = node5.SelectNodes("preceding-sibling::*"); //獲取當前節點(第一個title)開始之前的所有同級別節點
            foreach (XmlNode node in nodelist6)
            {
                Console.WriteLine(node.Name);   //輸出 id
            }

            XmlNode node7 = node5.SelectSingleNode("self::*");  
            Console.WriteLine(node7.Name);      //輸出 title

            Console.ReadKey();
        }

   4、XPath運算符

運算符 說明
| 計算兩個節點集
+ 加法
- 減法
* 乘法
div 除法
= 等於
!= 不等於
< 小於
<= 小於或等於
>= 大於或等於
> 大於
or
and
mod 計算除法的余數

  5、特殊字符

特殊字符 說明
/ 此路徑運算符出現在模式的開頭時,表示應從根節點選擇
// 從當前節點開始遞歸下降,此路徑運算符出現在模式開頭時表示應從節點遞歸下降
. 當前上下文
.. 當前上下文節點父節
* 通配符;選擇所有元素節點和元素名無關(不包括文本、注釋、指令等節點,如果也要包含這些節點請用node()函數)
@ 屬性的前綴
@* 所有的屬性,與名稱無關
: 命名空間分隔符;將命名空間前綴與元素名分隔
() 括號運算符(優先級最高),強制運算優先級
[] 應用篩選模式(即謂詞,包括"過濾表達式"和"軸"(向前/向后))
[] 下標運算符;用於在集合中編制索引

  6、XPath函數

 

    XPath與XSLT、XQuery等共享函數庫,函數庫提供了功能豐富的各種內置函數。

    (1)存取函數

     名稱              說明

     fn:node-name(node)      返回參數節點的節點名稱
     fn:nilled(node)         返回是否拒絕參數節點的布爾值
     fn:data(item.item,...)      接受項目序列,並返回原子序列
     fn:base-uri() fn:base-uri(node)返回當前節點的base-uri屬性的值
     fn:document-uri(node)     返回指定節點的document-uri屬性的值

    (2)錯誤和跟蹤函數

    名稱              說明

    fn:error()
    fn:error(error)
    fn:error(error,description)
    fn:error(error,description,error-object)
    fn:trace(value,label)      用於對查詢進行debug

    (3)有關數值的函數

    名稱              說明

    fn:number(arg)         返回參數的數值
    fn:abs(num)          返回參數的絕對值
    fn:ceiling(num)          返回大於num參數的最小整數
    fn:floor(num)          返回不大於num參數的最大整數
    fn:round(num)          把num參數舍入為最接近的整數
    fn:round-half-to-even()     不明白

    (4)有關字符串的函數

    名稱                說明

    fn:string(arg)            返回參數的字符串值。參數可以使數字、邏輯值或節點集
    fn:codepoints-to-string(int,int...)  根據代碼點序列返回字符串
    fn:string-to-codepoints(string)   根據字符串返回代碼點序列
    fn:codepoint-equal(comp1,comp2) 根據Unicode代碼點對照,如果comp1的值等於comp2的值則返回True
    fn:compare(comp1,comp2)     如果comp1小於comp2,則返回-1.相等返回0,如果comp1>comp2則返回1。
    fn:concat(string,string...)      返回字符串的拼接
    fn:string-join((string,string,...),sep) 使用sep參數作為分隔符,來返回string參數拼接后的字符串
    fn:substring(string,start,len)    返回從start位置開始的指定長度的子字符串。第一個字符的下標是1。如果省略len參數,則返回從位置start到字符串末尾的                        子字符串。
    fn:string-length(string)       返回指定字符串的長度,如果沒有string參數,則返回當前節點的字符串的值的長度。
    fn:normalize-space(string)      刪除指定字符串的開頭和結尾的空白,並把內部的所有空白序列替換為一個然后返回結果。
    fn:normalize-unicode()        執行Unicode規格化
    fn:upper-case(string)        把string參數轉換為大寫
    fn:lower-case(string)         把string參數轉換為小寫
    fn:translate(string1,string2,string3) 把string1中的string2替換為string3
    fn:escape-uri(stringURI,esc-res)   url編碼
    fn:contains(string1,string2)      如果string1包含string2則返回true,否則返回false
    fn:starts-with(string1,string2)    如果string1以string2開始,則返回true,否則返回false
    fn:ends-width(string1,string2)    如果string1以string2結尾,則返回true,否則返回false
    fn:substring-before(string1,string2) 返回string2在string1中出現之前的子字符串
    fn:substring-after(string1,string2)  返回string2在string1中出現之后的子字符串
    fn:matches(string,pattern)      如果string參數匹配指定的模式,則返回true,否則返回false
    fn:replace(string,pattern,replace)   把指定的模式替換為replace參數,並返回結果
    fn:tokenize(string,pattern)       pattern匹配到的字符進行分割,並將分割后的結果返回

   (5)上下文函數

    名稱                說明

    fn:position()            返回當前正在被處理的節點的index位置
    fn:last()               返回在被處理的節點列表中的項目數目
    fn:current-dateTime()        返回當前的dateTime(帶有時區)
    fn:current-date()          返回當前的日期(帶有時區)
    fn:current-time()          返回當前的時間(帶有時區)
    fn:implicit-timezone()         返回隱式時區的值
    fn:default-collation()        返回默認對照的值
    fn:static-base-uti()          返回base-uri的值

   (6)關於節點的函數

    名稱                  說明

    fn:name()/fn:name(nodeset)      返回當前節點的名稱或指定節點集的第一個節點
    fn:local-name()/fn:local-name(nodeset) 返回當前節點的名稱或指定節點集的第一個節點-不帶命名空
    fn:namespace-uri()/fn:namespace-uri(nodeset)     返回當前節點或指定節點集中第一個節點的命名空間URI
    fn:lang(lang)              如果當前節點的語言匹配指定的語言則返回True
    fn:root()/fn:root(node)         返回當前節點或指定節點所屬的節點樹的根節點。通常是文檔節點

 

   (7)一般性函數

    名稱                            說明

    fn:index-of((item,item,...),searchitem)           返回在項目序列中等於searchitem參數的位置
    fn:remove((item,item...),position)              返回由item參數構造的新序列-同時刪除position指定的項目
    fn:empty(item,item...)                   如果參數是空序列則返回True,否則返回False
    fn:exists(item,item,...)                   如果參數不是空序列,則返回True,否則返回False
    fn:distince-values((item,item,...),collation)         返回唯一不同的值
    fn:insert-before((item,item,...),pos,inserts)         返回由item參數構造的新序列 - 同時在pos參數指定位置插入inserts參數的值
    fn:reverse((item,item,...))                  返回指定的項目的顛倒順序
    fn:subsequence((item,item,...),start,len)          返回start參數指定的位置返回項目序列,序列的長度由len參數指定。第一個項目的位置是1
    fn:unordered                        依據事先決定的順序來返回項目

  (8)關於布爾值的函數

    名稱                       說明

    fn:boolean(arg)                 返回數字、字符串或節點集的布爾值
    fn:not(arg)                    首先通過boolean()函數把參數還原為一個布爾值,如果該布爾值為false則返回true,否則返回false
    fn:true()                    返回布爾值true
    fn:false()                     返回布爾值false

    由於函數實在太多,因此次數僅僅寫了幾個示例,展示下用法而已,一般都是寫在謂詞里。

        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();    //創建文檔
            doc.Load(@"C:\Users\Administrator\Desktop\ConsoleApplication1\ConsoleApplication1\Test.xml");     //加載xml文件

            XmlNode node1 = doc.SelectSingleNode("//title[contains(text(),'三')]");  //選取title元素,要求title的內容含有'三'
            Console.WriteLine(node1.InnerText);     //輸出 三國演義

            XmlNode node2 = doc.SelectSingleNode("//title[@lang='屬性2']");   //獲取屬性lang的值為屬性2的title節點,不管它位於何處
            Console.WriteLine(node2.InnerText);

            XmlNode node3 = doc.SelectSingleNode("//author[starts-with(text(),'吳')]");  //選取任意位置的author節點,其中author的元素值要以 吳 開頭
            Console.WriteLine(node3.InnerText);         //輸出 吳承恩

            XmlNode node4 = doc.SelectSingleNode("//title[string-length(text())>3]");   //選取值的長度大於3的title元素
            Console.WriteLine(node4.InnerText);     //輸出 三國演義

            XmlNode node5 = doc.SelectSingleNode("//price[floor(text())=38]");      //獲取 向下取整后值等於38的price元素
            Console.WriteLine(node5.InnerText);     //輸出 38.5

            Console.ReadKey();
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM