日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

XPath 详解,总结

發(fā)布時(shí)間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 XPath 详解,总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

XPath簡介

XPath是W3C的一個(gè)標(biāo)準(zhǔn)。它最主要的目的是為了在XML1.0或XML1.1文檔節(jié)點(diǎn)樹中定位節(jié)點(diǎn)所設(shè)計(jì)。目前有XPath1.0和XPath2.0兩個(gè)版本。其中Xpath1.0是1999年成為W3C標(biāo)準(zhǔn),而XPath2.0標(biāo)準(zhǔn)的確立是在2007年。W3C關(guān)于XPath的英文詳細(xì)文檔請見:http://www.w3.org/TR/xpath20/?。

XPath是一種表達(dá)式語言,它的返回值可能是節(jié)點(diǎn),節(jié)點(diǎn)集合,原子值,以及節(jié)點(diǎn)和原子值的混合等。XPath2.0是XPath1.0的超集。它是對XPath1.0的擴(kuò)展,它可以支持更加豐富的數(shù)據(jù)類型,并且XPath2.0保持了對XPath1.0的相對很好的向后兼容性,幾乎所有的XPath2.0的返回結(jié)果都可以和XPath1.0保持一樣。另外XPath2.0也是XSLT2.0和XQuery1.0的用于查詢定位節(jié)點(diǎn)的主表達(dá)式語言。XQuery1.0是對XPath2.0的擴(kuò)展。關(guān)于在XSLT和XQuery中使用XPath表達(dá)式定位節(jié)點(diǎn)的知識在后面的實(shí)例中會有所介紹。

在學(xué)習(xí)XPath之前你應(yīng)該對XML的節(jié)點(diǎn),元素,屬性,原子值(文本),處理指令,注釋,根節(jié)點(diǎn)(文檔節(jié)點(diǎn)),命名空間以及對節(jié)點(diǎn)間的關(guān)系如:父(Parent),子(Children),兄弟(Sibling),先輩(Ancestor),后代(Descendant)等概念有所了解。這里不在說明。

XPath路徑表達(dá)式

在本小節(jié)下面的內(nèi)容中你將可以學(xué)習(xí)到:

  • 路徑表達(dá)式語法
  • 相對/絕對路徑
  • 表達(dá)式上下文
  • 謂詞(篩選表達(dá)式)及軸的概念
  • 運(yùn)算符及特殊字符
  • 常用表達(dá)式實(shí)例
  • 函數(shù)及說明

這里給出一個(gè)實(shí)例Xml文件。下面的說明及實(shí)例都是基于該XML文件。

路徑表達(dá)式語法:?

  • 路徑 = 相對路徑 | 絕對路徑
  • XPath路徑表達(dá)式 = 步進(jìn)表達(dá)式 | 相對路徑 "/"步進(jìn)表達(dá)式。
  • 步進(jìn)表達(dá)式=軸 節(jié)點(diǎn)測試 謂詞
  • 說明:

  • 其中軸表示步進(jìn)表達(dá)式選擇的節(jié)點(diǎn)和當(dāng)前上下文節(jié)點(diǎn)間的樹狀關(guān)系(層次關(guān)系),節(jié)點(diǎn)測試指定步進(jìn)表達(dá)式選擇的節(jié)點(diǎn)名稱擴(kuò)展名,謂詞即相當(dāng)于過濾表達(dá)式以進(jìn)一步過濾細(xì)化節(jié)點(diǎn)集。
  • 謂詞可以是0個(gè)或多個(gè)。多個(gè)多個(gè)謂詞用邏輯操作符and, or連接。取邏輯非用not()函數(shù)。
  • 請看一個(gè)典型的XPath查詢表達(dá)式:/messages/message//child::node()[@id=0],其中/messages/message是路徑(絕對路徑以"/"開始),child::是軸表示在子節(jié)點(diǎn)下選擇,node()是節(jié)點(diǎn)測試表示選擇所有的節(jié)點(diǎn)。[@id=0]是謂詞,表示選擇所有有屬性id并且值為0的節(jié)點(diǎn)。 相對路徑與絕對路徑: 如果"/"處在XPath表達(dá)式開頭則表示文檔根元素,(表達(dá)式中間作為分隔符用以分割每一個(gè)步進(jìn)表達(dá)式)如:/messages/message/subject是一種絕對路徑表示法,它表明是從文檔根開始查找節(jié)點(diǎn)。假設(shè)當(dāng)前節(jié)點(diǎn)是在第一個(gè)message節(jié)點(diǎn)【/messages/message[1]】,則路徑表達(dá)式subject(路徑前沒有"/")這種表示法稱為相對路徑,表明從當(dāng)前節(jié)點(diǎn)開始查找。具體請見下面所述的"表達(dá)式上下文"。 表達(dá)式上下文(Context): 上下文其實(shí)表示一種環(huán)境。以明確當(dāng)前XPath路徑表達(dá)式處在什么樣的環(huán)境下執(zhí)行。例如同樣一個(gè)路徑表達(dá)式處在對根節(jié)點(diǎn)操作的環(huán)境和處在對某一個(gè)特定子節(jié)點(diǎn)操作的環(huán)境下執(zhí)行所獲得的結(jié)果可能是完全不一樣的。也就是說XPath路徑表達(dá)式計(jì)算結(jié)果取決于它所處的上下文。 XPath上下文基本有以下幾種
    • 當(dāng)前節(jié)點(diǎn)(./):?
      如./sender表示選擇當(dāng)前節(jié)點(diǎn)下的sender節(jié)點(diǎn)集合(等同于下面所講的"特定元素",如:sender)
    • 父節(jié)點(diǎn)(../):?
      如../sender表示選擇當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)下的sender節(jié)點(diǎn)集合
    • 根元素(/):?
      如/messages表示選擇從文檔根節(jié)點(diǎn)下的messages節(jié)點(diǎn)集合.
    • 根節(jié)點(diǎn)(/*):?
      這里的*是代表所有節(jié)點(diǎn),但是根元素只有一個(gè),所以這里表示根節(jié)點(diǎn)。/*的返回結(jié)果和/messages返回的結(jié)果一樣都是messages節(jié)點(diǎn)。
    • 遞歸下降(//):?
      如當(dāng)前上下文是messages節(jié)點(diǎn)。則//sender將返回以下結(jié)果:?
      /messages//sender :?
      <sender>gkt1980@gmail.com</sender>?
      <sender>111@gmail.com</sender>?
      <sender>333@gmail.com</sender>?

      /messages/message[1]//sender:?
      <sender>gkt1980@gmail.com</sender>?
      <sender>111@gmail.com</sender>?

      我們可以看出XPath表達(dá)式返回的結(jié)果是:從當(dāng)前節(jié)點(diǎn)開始遞歸步進(jìn)搜索當(dāng)前節(jié)點(diǎn)下的所有子節(jié)點(diǎn)找到滿足條件的節(jié)點(diǎn)集。
    • 特定元素?
      如sender:表示選擇當(dāng)前節(jié)點(diǎn)下的sender節(jié)點(diǎn)集合,等同于(./sender)
    注意:在執(zhí)行XPath時(shí)一定要注意上下文。即當(dāng)前是在哪個(gè)節(jié)點(diǎn)下執(zhí)行XPath表達(dá)式。這在XMLDOM中很重要。如:在XMLDOM中的selectNodes,selectSingleNode方法的參數(shù)都是一個(gè)XPath表達(dá)式,此時(shí)這個(gè)XPath表達(dá)式的執(zhí)行上下文就是調(diào)用這個(gè)方法的節(jié)點(diǎn)及它所在的環(huán)境。更多信息請參見:http://www.w3.org/TR/xpath20/ 謂詞(篩選表達(dá)式)及軸的概念: XPath的謂詞即篩選表達(dá)式,類似于SQL的where子句.

    ?

    軸名稱 結(jié)果
    ancestor 選取當(dāng)前節(jié)點(diǎn)的所有先輩(父、祖父等)
    ancestor-or-self 選取當(dāng)前節(jié)點(diǎn)的所有先輩(父、祖父等)以及當(dāng)前節(jié)點(diǎn)本身
    attribute 選取當(dāng)前節(jié)點(diǎn)的所有屬性
    child 選取當(dāng)前節(jié)點(diǎn)的所有子元素。
    descendant 選取當(dāng)前節(jié)點(diǎn)的所有后代元素(子、孫等)。
    descendant-or-self 選取當(dāng)前節(jié)點(diǎn)的所有后代元素(子、孫等)以及當(dāng)前節(jié)點(diǎn)本身。
    following 選取文檔中當(dāng)前節(jié)點(diǎn)的結(jié)束標(biāo)簽之后的所有節(jié)點(diǎn)。
    namespace 選取當(dāng)前節(jié)點(diǎn)的所有命名空間節(jié)點(diǎn)
    parent 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。
    preceding 直到所有這個(gè)節(jié)點(diǎn)的父輩節(jié)點(diǎn),順序選擇每個(gè)父輩節(jié)點(diǎn)前的所有同級節(jié)點(diǎn)
    preceding-sibling 選取當(dāng)前節(jié)點(diǎn)之前的所有同級節(jié)點(diǎn)。
    self 選取當(dāng)前節(jié)點(diǎn)。

    ?

    運(yùn)算符及特殊字符:

    ?

    運(yùn)算符/特殊字符 說明
    / 此路徑運(yùn)算符出現(xiàn)在模式開頭時(shí),表示應(yīng)從根節(jié)點(diǎn)選擇。
    // 從當(dāng)前節(jié)點(diǎn)開始遞歸下降,此路徑運(yùn)算符出現(xiàn)在模式開頭時(shí),表示應(yīng)從根節(jié)點(diǎn)遞歸下降。
    . 當(dāng)前上下文。
    .. 當(dāng)前上下文節(jié)點(diǎn)父級。
    * 通配符;選擇所有元素節(jié)點(diǎn)與元素名無關(guān)。(不包括文本,注釋,指令等節(jié)點(diǎn),如果也要包含這些節(jié)點(diǎn)請用node()函數(shù))
    @ 屬性名的前綴。
    @* 選擇所有屬性,與名稱無關(guān)。
    : 命名空間分隔符;將命名空間前綴與元素名或?qū)傩悦指簟?
    ( ) 括號運(yùn)算符(優(yōu)先級最高),強(qiáng)制運(yùn)算優(yōu)先級。
    [ ] 應(yīng)用篩選模式(即謂詞,包括"過濾表達(dá)式"和"軸(向前/向后)")。
    [ ] 下標(biāo)運(yùn)算符;用于在集合中編制索引。
    | 兩個(gè)節(jié)點(diǎn)集合的聯(lián)合,如://messages/message/to | //messages/message/cc
    - 減法。
    div, 浮點(diǎn)除法。
    and, or 邏輯運(yùn)算。
    mod 求余。
    not() 邏輯非
    = 等于
    != 不等于
    特殊比較運(yùn)算符 < 或者 &lt; <= 或者 &lt;= > 或者 &gt; >= 或者 &gt;= 需要轉(zhuǎn)義的時(shí)候必須使用轉(zhuǎn)義的形式,如在XSLT中,而在XMLDOM的scripting中不需要轉(zhuǎn)義。

    ?

    常用表達(dá)式實(shí)例:

    ?

    / Document Root文檔根.
    /* 選擇文檔根下面的所有元素節(jié)點(diǎn),即根節(jié)點(diǎn)(XML文檔只有一個(gè)根節(jié)點(diǎn))
    /node() 根元素下所有的節(jié)點(diǎn)(包括文本節(jié)點(diǎn),注釋節(jié)點(diǎn)等)
    /text() 查找文檔根節(jié)點(diǎn)下的所有文本節(jié)點(diǎn)
    /messages/message messages節(jié)點(diǎn)下的所有message節(jié)點(diǎn)
    /messages/message[1] messages節(jié)點(diǎn)下的第一個(gè)message節(jié)點(diǎn)
    /messages/message[1]/self::node() 第一個(gè)message節(jié)點(diǎn)(self軸表示自身,node()表示選擇所有節(jié)點(diǎn))
    /messages/message[1]/node() 第一個(gè)message節(jié)點(diǎn)下的所有子節(jié)點(diǎn)
    /messages/message[1]/*[last()] 第一個(gè)message節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)
    /messages/message[1]/[last()] Error,謂詞前必須是節(jié)點(diǎn)或節(jié)點(diǎn)集
    /messages/message[1]/node()[last()] 第一個(gè)message節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)
    /messages/message[1]/text() 第一個(gè)message節(jié)點(diǎn)的所有子節(jié)點(diǎn)
    /messages/message[1]//text() 第一個(gè)message節(jié)點(diǎn)下遞歸下降查找所有的文本節(jié)點(diǎn)(無限深度)
    /messages/message[1] /child::node() /messages/message[1] /node() /messages/message[position()=1]/node() //message[@id=1] /node() 第一個(gè)message節(jié)點(diǎn)下的所有子節(jié)點(diǎn)
    //message[@id=1] //child::node() 遞歸所有子節(jié)點(diǎn)(無限深度)
    //message[position()=1]/node() 選擇id=1的message節(jié)點(diǎn)以及id=0的message節(jié)點(diǎn)
    /messages/message[1] /parent::* Messages節(jié)點(diǎn)
    /messages/message[1]/body/attachments/parent::node() /messages/message[1]/body/attachments/parent::* /messages/message[1]/body/attachments/.. attachments節(jié)點(diǎn)的父節(jié)點(diǎn)。父節(jié)點(diǎn)只有一個(gè),所以node()和* 返回結(jié)果一樣。 (..也表示父節(jié)點(diǎn). 表示自身節(jié)點(diǎn))
    //message[@id=0]/ancestor::* Ancestor軸表示所有的祖輩,父,祖父等。 向上遞歸
    //message[@id=0]/ancestor-or-self::* 向上遞歸,包含自身
    //message[@id=0]/ancestor::node() 對比使用*,多一個(gè)文檔根元素(Document root)
    /messages/message[1]/descendant::node() //messages/message[1]//node() 遞歸下降查找message節(jié)點(diǎn)的所有節(jié)點(diǎn)
    /messages/message[1]/sender/following::* 查找第一個(gè)message節(jié)點(diǎn)的sender節(jié)點(diǎn)后的所有同級節(jié)點(diǎn),并對每一個(gè)同級節(jié)點(diǎn)遞歸向下查找。
    //message[@id=1]/sender/following-sibling::* 查找id=1的message節(jié)點(diǎn)的sender節(jié)點(diǎn)的所有后續(xù)的同級節(jié)點(diǎn)。
    //message[@id=1]/datetime/@date 查找id=1的message節(jié)點(diǎn)的datetime節(jié)點(diǎn)的date屬性
    //message[@id=1]/datetime[@date] //message/datetime[attribute::date] 查找id=1的message節(jié)點(diǎn)的所有含有date屬性的datetime節(jié)點(diǎn)
    //message[datetime] 查找所有含有datetime節(jié)點(diǎn)的message節(jié)點(diǎn)
    //message/datetime/attribute::* //message/datetime/attribute::node() //message/datetime/@* 返回message節(jié)點(diǎn)下datetime節(jié)點(diǎn)的所有屬性節(jié)點(diǎn)
    //message/datetime[attribute::*] //message/datetime[attribute::node()] //message/datetime[@*] //message/datetime[@node()] 選擇所有含有屬性的datetime節(jié)點(diǎn)
    //attribute::* 選擇根節(jié)點(diǎn)下的所有屬性節(jié)點(diǎn)
    //message[@id=0]/body/preceding::node() 順序選擇body節(jié)點(diǎn)所在節(jié)點(diǎn)前的所有同級節(jié)點(diǎn)。(查找順序?yàn)?#xff1a;先找到body節(jié)點(diǎn)的頂級節(jié)點(diǎn)(根節(jié)點(diǎn)),得到根節(jié)點(diǎn)標(biāo)簽前的所有同級節(jié)點(diǎn),執(zhí)行完成后繼續(xù)向下一級,順序得到該節(jié)點(diǎn)標(biāo)簽前的所有同級節(jié)點(diǎn),依次類推。) 注意:查找同級節(jié)點(diǎn)是順序查找,而不是遞歸查找。
    //message[@id=0]/body/preceding-sibling::node() 順序查找body標(biāo)簽前的所有同級節(jié)點(diǎn)。(和上例一個(gè)最大的區(qū)別是:不從最頂層開始到body節(jié)點(diǎn)逐層查找。我們可以理解成少了一個(gè)循環(huán),而只查找當(dāng)前節(jié)點(diǎn)前的同級節(jié)點(diǎn))
    //message[@id=1]//*[namespace::amazon] 查找id=1的所有message節(jié)點(diǎn)下的所有命名空間為amazon的節(jié)點(diǎn)。
    //namespace::* 文檔中的所有的命名空間節(jié)點(diǎn)。(包括默認(rèn)命名空間xmlns:xml)
    //message[@id=0]//books/*[local-name()='book'] 選擇books下的所有的book節(jié)點(diǎn), 注意:由于book節(jié)點(diǎn)定義了命名空間<amazone:book>.若寫成//message[@id=0]//books/book則查找不出任何節(jié)點(diǎn)。
    //message[@id=0]//books/*[local-name()='book' and namespace-uri()='http://www.amazon.com/books/schema'] 選擇books下的所有的book節(jié)點(diǎn),(節(jié)點(diǎn)名和命名空間都匹配)
    //message[@id=0]//books/*[local-name()='book'][year>2006] 選擇year節(jié)點(diǎn)值>2006的book節(jié)點(diǎn)
    //message[@id=0]//books/*[local-name()='book'][1]/year>2006 指示第一個(gè)book節(jié)點(diǎn)的year節(jié)點(diǎn)值是否大于2006. 返回xs:boolean: true

    ?

    函數(shù)及說明:? 值得欣喜的是XPath函數(shù)和XSLT,XQuery等共享函數(shù)庫,函數(shù)庫為我們提供了功能豐富的各種函數(shù)的調(diào)用,我們也可以自定義自己的函數(shù)。這里不再對每個(gè)函數(shù)的用法逐一說明,英文好點(diǎn)的朋友直接去看看w3關(guān)于XPath函數(shù)的介紹吧:http://www.w3.org/TR/xquery-operators?。中文的可以參考這個(gè)網(wǎng)站,?http://www.w3school.com.cn/xpath/xpath_functions.asp XPath在DOM,XSLT及XQuery中的應(yīng)用

    ?

    ?

    <!DOCTYPE?html?PUBLIC?"-//W3C//DTD?XHTML?1.0?Transitional//EN"?"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">?
    <html?xmlns="http://www.w3.org/1999/xhtml">?
    <head>?
    <title>XPath?Test</title>?
    </head>?
    <body>?

    <script?language="javascript"?type="text/javascript">?
    var?xmlDoc?=?new?ActiveXObject("Microsoft.XMLDOM");?
    xmlDoc.async="false";?
    xmlDoc.load("messages.xml");?
    xmlDoc.setProperty("SelectionLanguage",?"XPath");?
    ????var?sPath?=?"/messages/message[1]//books/*[local-name()='book']";?
    var?bookNodes?=?xmlDoc.selectNodes(sPath);?

    document.write("<ul>");?
    for?(?var?i?=?0;?i?<?bookNodes.length;?i++)?{?
    document.write("<li>"?+?bookNodes[i].childNodes[0].text?+?"</li>");?
    }?
    document.write("</ul>");?
    </script>?

    </body>?
    </html>

    ?

    注意: 我們?nèi)羰褂胣ew ActiveXObject("Microsoft.XMLDOM")則需要注意的是:因?yàn)樵缙诘腦MLDOM的SelectionLanguage屬性默認(rèn)是正則表達(dá)式,不是XPath語言。所以需要指定這樣一條語句xmlDoc.setProperty("SelectionLanguage", "XPath"); 以支持XPath查詢表達(dá)式。. 若沒有指定SelectionLanguage屬性值為XPath則要注意以下情況:
  • 數(shù)組下標(biāo)從0開始(我們知道在XPath查詢表達(dá)式中數(shù)組下標(biāo)是從1開始的)
  • 不支持在XPath查詢表達(dá)式中使用XPath函數(shù)。
  • XSLT:?
    見:我的另外一篇關(guān)于如何使用XSLT的一個(gè)小示范http://www.cnblogs.com/ktgu/archive/2008/12/14/1354890.html XQuery:?

    ?

    xquery?version?"1.0";?

    <ul>?
    {?
    let?$i?:=?0?
    for?$x?in?doc("C:\Users\Administrator\Desktop\messages.xml")//message[@id=0]//books/*[local-name()='book']?
    where?$x/year>2006?
    order?by?$x/year?descending?
    return?<li>{?data($x/name)?}?</li>?
    }?
    </ul>

    ?

    返回結(jié)果

    <ul>?
    ??? <li>Microsoft Visual C# 2008 Step by Step </li>?
    ??? <li>Professional C# 2008 </li>?
    </ul>
    本文轉(zhuǎn)自左正博客園博客,原文鏈接:http://www.cnblogs.com/soundcode/p/3807167.html,如需轉(zhuǎn)載請自行聯(lián)系原作者 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的XPath 详解,总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。