XPath詳細介紹
XPath是XML路徑語言,W3C的一個標準。它最主要的目的是為了在XML1.0或XML1.1文檔節點樹中定位節點所設計。目前 XPath1.0和XPath2.0兩個版本。其中XPath1.0是1999年成為W3C標準,而XPath2.0標準的確立是在2007年。
XPath是一種表達式語言,它的返回值可能是節點,節點集合,原子值,以及節點和原子值的混合等。XPath2.0是XPath1.0的超集,它 是對XPath1.0的擴展,它可以支持更加豐富的數據類型,并且XPath2.0保持了對XPath1.0的相對很好的向后兼容性,幾乎所有的 XPath2.0的返回結果都可以和XPath1.0保持一樣。另外XPath2.0也是XSLT2.0和XQuery1.0的用于查詢定位節點的主表達 式語言。
在學習XPath之前你應該對XML的節點,元素,屬性,原子值(文本),處理指令,注釋,根節點(文檔節點),命名空間以及對節點間的關系如:父 (Parent),子(Children),兄弟(Sibling),先輩(Ancestor),后代(Descendant)等概念有所了解。這里不在 說明。
路徑表達式語法
-
路徑 = 相對路徑 | 絕對路徑
-
XPath路徑表達式 = 步進表達式 | 相對路徑 “/” 步進表達式。
-
步進表達式 = 軸 節點測試 謂詞
說明:1. 其中軸表示步進表達式選擇的節點和當前上下文節點間的樹狀關系(層次關系),節點測試指定步進表達式選擇的節點名稱擴展名,謂詞即相當于過濾表達式以進一 步過濾細化節點集。2. 謂詞可以是0個或多個。多個謂詞用邏輯操作符and,or連接。取邏輯非用not()函數。
請看一個典型的XPath查詢表達式:/messages/message//child::node()[@id=0], 其中/messages/message是路徑(絕對路徑以“/”開始),child::是軸表示在子節點下選擇,node()是節點測試表示選擇所有的 節點。[@id=0]是謂詞,表示選擇所有有屬性id并值為0的節點。
相對路徑與絕對路徑
如果“/”處在XPath表達式開頭則表示文件根元素,(表達式中間作為分隔符用以分割每一個步進表達式)如:/messages/message /subject是一種絕對路徑表示法,它表明是從文檔根開始查找節點。假設當前節點是在第一個message節點(/messages /message[1]),則路徑表達式subject(路徑前沒有“/”)這種表示法稱為相對路徑,表明從當前節點開始查找。
表達式上下文(Context)
上下文其實表示一種環境。以明確當前XPath路徑表達式處在什么樣的環境下執行。例如同樣一個路徑表達式處在對根節點操作的環境和處在對某一個特定子節點操作的環境下執行所獲得的結果可能是完全不一樣的。也就是說XPath路徑表達式計算結果取決于它所處的上下文。
XPath上下文基本有以下幾種:
-
當前節點(./):如./sender表達式選擇當前節點下的sender節點集合(等同于下面所講的“特定元素”,如:sender)
-
父節點(../):如../sender表示選擇當前節點的父節點下的sender節點集合
-
根節點(/*):這里的*是代表所有節點,但是根元素只有一個,所以這里表示根節點。/*的返回結果和/messages返回的結果一樣都是messages節點。
-
遞歸下降(//):如例 /messages//sender。從當前節點messages開始遞歸步進搜索當前節點下的所有子節點找到滿足條件的節點sender集。
-
特定元素:如sender,表示選擇當前節點下的sender節點集合,等同于(./sender)。
注意:在執行XPath時一定要注意上下文。即當前是在哪個節點下執行XPath表達式。這在XML的DOM中很重要。
謂詞(篩選表達式)及軸的概念
XPath的謂詞即篩選表達式,類似于SQL的where子句:
軸名稱 |
結果 |
ancestor |
選取當前節點的所有先輩(父,祖父等) |
ancestor-or-self |
選取當前節點的所有先輩(父,祖父等)以及當前節點本身 |
attribute |
選取當前節點的所有屬性 |
child |
選取當前節點的所有子元素 |
descendant |
選取當前節點的所有后代元素(子,孫等) |
descendant-or-self |
選取當前節點的所有后代元素(子,孫等)以及當前節點本身 |
following |
選取文檔中當前節點的結束標簽之后的所有節點。 |
namespace |
選取當前節點的所有命名空間節點 |
parent |
選取當前節點的父節點 |
preceding |
找到所有這個節點的父輩節點,順序選擇每個父輩節點前的所有同級節點。 |
self |
選取當前節點 |
運算符及特殊字符:
運算符/特殊字符 |
說明 |
/ |
此路徑運算符出現在模式開頭時,表示應從根節點選擇 |
// |
從當前節點開始遞歸下降,此路徑運算符出現在模式開頭時,表示應用根節點遞歸下降 |
. |
當前上下文 |
.. |
當前上下文節點父級 |
* |
通配符,選擇所有元素節點與元素名無關。(不包括文本,注釋,指令等節點,如果也要包含這些節點請用node()函數) |
@ |
屬性名的前綴 |
@* |
選擇所有屬性,與名稱無關 |
: |
命名空間分隔符,將命名空間前綴與元素名或屬性名分隔 |
() |
括號運算符(優先級最高),強制運算優先級 |
[] |
應用篩選模式(即謂詞,包括“過濾表達式”和“軸(向前/向后)”) 另一種表示下票運算符,用于在集合中編制索引 |
| |
兩個節點集合的聯合,如://messages/message/to | //messages/message/cc |
- |
減法 |
div , |
浮點除法 |
and , or |
邏輯運算 |
mod |
求余 |
not() |
邏輯非 |
= |
等于 |
!= |
不等于 |
特殊比較運算符 |
< 或者 < <= 或者 <= > 或者 > >= 或者 >= 需要轉義的時候必須使用轉義的形式 |
常用表達式實例:
/ |
Document Root文檔根 |
/* |
選擇文檔根下面的所有元素節點,即根節點(XML文檔只有一個根節點) |
/node() |
根元素下所有的節點(包括文本節點,注釋節點等) |
/text() |
查找文檔根節點下的所有文本節點 |
/messages/message |
messages節點下的所有message節點 |
/messages/message[1] |
messages節點下的第一個message節點 |
/messages/message[1]/self::node() |
第一個message節點(self軸表示自身,node()表示選擇所有節點) |
/messages/message[1]/node() |
第一個message節點下的所有子節點 |
/messages/message[1]/*[last()] |
每一個message節點的最后一個子節點 |
/messages/message[1]/[last()] |
Error,謂詞前必須是節點或節點集 |
/messages/message[1]/node()[last()] |
第一個message節點的最后一個子節點 |
/messages/message[1]/text() |
每一個message節點下的所有文本節點 |
/messages/message[1]//text() |
第一個message節點下遞歸下降查找所有的文本節點(無限深度) |
/messages/message[1]/child::node() /messages/message[1]/node() /messages/message[position()=1]/mode() //message[@id=1]/node() |
第一個message節點下的所有子節點 |
//message[@id=1]//child:node() |
遞歸所有子節點(無限深度) |