XPath 详解,总结
XPath簡介
XPath是W3C的一個標準。它最主要的目的是為了在XML1.0或XML1.1文檔節(jié)點樹中定位節(jié)點所設計。目前有XPath1.0和XPath2.0兩個版本。其中Xpath1.0是1999年成為W3C標準,而XPath2.0標準的確立是在2007年。W3C關于XPath的英文詳細文檔請見:http://www.w3.org/TR/xpath20/?。
XPath是一種表達式語言,它的返回值可能是節(jié)點,節(jié)點集合,原子值,以及節(jié)點和原子值的混合等。XPath2.0是XPath1.0的超集。它是對XPath1.0的擴展,它可以支持更加豐富的數(shù)據(jù)類型,并且XPath2.0保持了對XPath1.0的相對很好的向后兼容性,幾乎所有的XPath2.0的返回結果都可以和XPath1.0保持一樣。另外XPath2.0也是XSLT2.0和XQuery1.0的用于查詢定位節(jié)點的主表達式語言。XQuery1.0是對XPath2.0的擴展。關于在XSLT和XQuery中使用XPath表達式定位節(jié)點的知識在后面的實例中會有所介紹。
在學習XPath之前你應該對XML的節(jié)點,元素,屬性,原子值(文本),處理指令,注釋,根節(jié)點(文檔節(jié)點),命名空間以及對節(jié)點間的關系如:父(Parent),子(Children),兄弟(Sibling),先輩(Ancestor),后代(Descendant)等概念有所了解。這里不在說明。
XPath路徑表達式
在本小節(jié)下面的內容中你將可以學習到:
- 路徑表達式語法
- 相對/絕對路徑
- 表達式上下文
- 謂詞(篩選表達式)及軸的概念
- 運算符及特殊字符
- 常用表達式實例
- 函數(shù)及說明
這里給出一個實例Xml文件。下面的說明及實例都是基于該XML文件。
路徑表達式語法:?
說明:
- 當前節(jié)點(./):?
如./sender表示選擇當前節(jié)點下的sender節(jié)點集合(等同于下面所講的"特定元素",如:sender) - 父節(jié)點(../):?
如../sender表示選擇當前節(jié)點的父節(jié)點下的sender節(jié)點集合 - 根元素(/):?
如/messages表示選擇從文檔根節(jié)點下的messages節(jié)點集合. - 根節(jié)點(/*):?
這里的*是代表所有節(jié)點,但是根元素只有一個,所以這里表示根節(jié)點。/*的返回結果和/messages返回的結果一樣都是messages節(jié)點。 - 遞歸下降(//):?
如當前上下文是messages節(jié)點。則//sender將返回以下結果:?
/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表達式返回的結果是:從當前節(jié)點開始遞歸步進搜索當前節(jié)點下的所有子節(jié)點找到滿足條件的節(jié)點集。 - 特定元素?
如sender:表示選擇當前節(jié)點下的sender節(jié)點集合,等同于(./sender)
?
| 軸名稱 | 結果 |
| ancestor | 選取當前節(jié)點的所有先輩(父、祖父等) |
| ancestor-or-self | 選取當前節(jié)點的所有先輩(父、祖父等)以及當前節(jié)點本身 |
| attribute | 選取當前節(jié)點的所有屬性 |
| child | 選取當前節(jié)點的所有子元素。 |
| descendant | 選取當前節(jié)點的所有后代元素(子、孫等)。 |
| descendant-or-self | 選取當前節(jié)點的所有后代元素(子、孫等)以及當前節(jié)點本身。 |
| following | 選取文檔中當前節(jié)點的結束標簽之后的所有節(jié)點。 |
| namespace | 選取當前節(jié)點的所有命名空間節(jié)點 |
| parent | 選取當前節(jié)點的父節(jié)點。 |
| preceding | 直到所有這個節(jié)點的父輩節(jié)點,順序選擇每個父輩節(jié)點前的所有同級節(jié)點 |
| preceding-sibling | 選取當前節(jié)點之前的所有同級節(jié)點。 |
| self | 選取當前節(jié)點。 |
?
運算符及特殊字符:?
| 運算符/特殊字符 | 說明 |
| / | 此路徑運算符出現(xiàn)在模式開頭時,表示應從根節(jié)點選擇。 |
| // | 從當前節(jié)點開始遞歸下降,此路徑運算符出現(xiàn)在模式開頭時,表示應從根節(jié)點遞歸下降。 |
| . | 當前上下文。 |
| .. | 當前上下文節(jié)點父級。 |
| * | 通配符;選擇所有元素節(jié)點與元素名無關。(不包括文本,注釋,指令等節(jié)點,如果也要包含這些節(jié)點請用node()函數(shù)) |
| @ | 屬性名的前綴。 |
| @* | 選擇所有屬性,與名稱無關。 |
| : | 命名空間分隔符;將命名空間前綴與元素名或屬性名分隔。 |
| ( ) | 括號運算符(優(yōu)先級最高),強制運算優(yōu)先級。 |
| [ ] | 應用篩選模式(即謂詞,包括"過濾表達式"和"軸(向前/向后)")。 |
| [ ] | 下標運算符;用于在集合中編制索引。 |
| | | 兩個節(jié)點集合的聯(lián)合,如://messages/message/to | //messages/message/cc |
| - | 減法。 |
| div, | 浮點除法。 |
| and, or | 邏輯運算。 |
| mod | 求余。 |
| not() | 邏輯非 |
| = | 等于 |
| != | 不等于 |
| 特殊比較運算符 | < 或者 < <= 或者 <= > 或者 > >= 或者 >= 需要轉義的時候必須使用轉義的形式,如在XSLT中,而在XMLDOM的scripting中不需要轉義。 |
?
常用表達式實例:?
| / | Document Root文檔根. |
| /* | 選擇文檔根下面的所有元素節(jié)點,即根節(jié)點(XML文檔只有一個根節(jié)點) |
| /node() | 根元素下所有的節(jié)點(包括文本節(jié)點,注釋節(jié)點等) |
| /text() | 查找文檔根節(jié)點下的所有文本節(jié)點 |
| /messages/message | messages節(jié)點下的所有message節(jié)點 |
| /messages/message[1] | messages節(jié)點下的第一個message節(jié)點 |
| /messages/message[1]/self::node() | 第一個message節(jié)點(self軸表示自身,node()表示選擇所有節(jié)點) |
| /messages/message[1]/node() | 第一個message節(jié)點下的所有子節(jié)點 |
| /messages/message[1]/*[last()] | 第一個message節(jié)點的最后一個子節(jié)點 |
| /messages/message[1]/[last()] | Error,謂詞前必須是節(jié)點或節(jié)點集 |
| /messages/message[1]/node()[last()] | 第一個message節(jié)點的最后一個子節(jié)點 |
| /messages/message[1]/text() | 第一個message節(jié)點的所有子節(jié)點 |
| /messages/message[1]//text() | 第一個message節(jié)點下遞歸下降查找所有的文本節(jié)點(無限深度) |
| /messages/message[1] /child::node() /messages/message[1] /node() /messages/message[position()=1]/node() //message[@id=1] /node() | 第一個message節(jié)點下的所有子節(jié)點 |
| //message[@id=1] //child::node() | 遞歸所有子節(jié)點(無限深度) |
| //message[position()=1]/node() | 選擇id=1的message節(jié)點以及id=0的message節(jié)點 |
| /messages/message[1] /parent::* | Messages節(jié)點 |
| /messages/message[1]/body/attachments/parent::node() /messages/message[1]/body/attachments/parent::* /messages/message[1]/body/attachments/.. | attachments節(jié)點的父節(jié)點。父節(jié)點只有一個,所以node()和* 返回結果一樣。 (..也表示父節(jié)點. 表示自身節(jié)點) |
| //message[@id=0]/ancestor::* | Ancestor軸表示所有的祖輩,父,祖父等。 向上遞歸 |
| //message[@id=0]/ancestor-or-self::* | 向上遞歸,包含自身 |
| //message[@id=0]/ancestor::node() | 對比使用*,多一個文檔根元素(Document root) |
| /messages/message[1]/descendant::node() //messages/message[1]//node() | 遞歸下降查找message節(jié)點的所有節(jié)點 |
| /messages/message[1]/sender/following::* | 查找第一個message節(jié)點的sender節(jié)點后的所有同級節(jié)點,并對每一個同級節(jié)點遞歸向下查找。 |
| //message[@id=1]/sender/following-sibling::* | 查找id=1的message節(jié)點的sender節(jié)點的所有后續(xù)的同級節(jié)點。 |
| //message[@id=1]/datetime/@date | 查找id=1的message節(jié)點的datetime節(jié)點的date屬性 |
| //message[@id=1]/datetime[@date] //message/datetime[attribute::date] | 查找id=1的message節(jié)點的所有含有date屬性的datetime節(jié)點 |
| //message[datetime] | 查找所有含有datetime節(jié)點的message節(jié)點 |
| //message/datetime/attribute::* //message/datetime/attribute::node() //message/datetime/@* | 返回message節(jié)點下datetime節(jié)點的所有屬性節(jié)點 |
| //message/datetime[attribute::*] //message/datetime[attribute::node()] //message/datetime[@*] //message/datetime[@node()] | 選擇所有含有屬性的datetime節(jié)點 |
| //attribute::* | 選擇根節(jié)點下的所有屬性節(jié)點 |
| //message[@id=0]/body/preceding::node() | 順序選擇body節(jié)點所在節(jié)點前的所有同級節(jié)點。(查找順序為:先找到body節(jié)點的頂級節(jié)點(根節(jié)點),得到根節(jié)點標簽前的所有同級節(jié)點,執(zhí)行完成后繼續(xù)向下一級,順序得到該節(jié)點標簽前的所有同級節(jié)點,依次類推。) 注意:查找同級節(jié)點是順序查找,而不是遞歸查找。 |
| //message[@id=0]/body/preceding-sibling::node() | 順序查找body標簽前的所有同級節(jié)點。(和上例一個最大的區(qū)別是:不從最頂層開始到body節(jié)點逐層查找。我們可以理解成少了一個循環(huán),而只查找當前節(jié)點前的同級節(jié)點) |
| //message[@id=1]//*[namespace::amazon] | 查找id=1的所有message節(jié)點下的所有命名空間為amazon的節(jié)點。 |
| //namespace::* | 文檔中的所有的命名空間節(jié)點。(包括默認命名空間xmlns:xml) |
| //message[@id=0]//books/*[local-name()='book'] | 選擇books下的所有的book節(jié)點, 注意:由于book節(jié)點定義了命名空間<amazone:book>.若寫成//message[@id=0]//books/book則查找不出任何節(jié)點。 |
| //message[@id=0]//books/*[local-name()='book' and namespace-uri()='http://www.amazon.com/books/schema'] | 選擇books下的所有的book節(jié)點,(節(jié)點名和命名空間都匹配) |
| //message[@id=0]//books/*[local-name()='book'][year>2006] | 選擇year節(jié)點值>2006的book節(jié)點 |
| //message[@id=0]//books/*[local-name()='book'][1]/year>2006 | 指示第一個book節(jié)點的year節(jié)點值是否大于2006. 返回xs:boolean: true |
?
函數(shù)及說明:? 值得欣喜的是XPath函數(shù)和XSLT,XQuery等共享函數(shù)庫,函數(shù)庫為我們提供了功能豐富的各種函數(shù)的調用,我們也可以自定義自己的函數(shù)。這里不再對每個函數(shù)的用法逐一說明,英文好點的朋友直接去看看w3關于XPath函數(shù)的介紹吧:http://www.w3.org/TR/xquery-operators?。中文的可以參考這個網站,?http://www.w3school.com.cn/xpath/xpath_functions.asp XPath在DOM,XSLT及XQuery中的應用?
?
<!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>
?
注意: 我們若使用new ActiveXObject("Microsoft.XMLDOM")則需要注意的是:因為早期的XMLDOM的SelectionLanguage屬性默認是正則表達式,不是XPath語言。所以需要指定這樣一條語句xmlDoc.setProperty("SelectionLanguage", "XPath"); 以支持XPath查詢表達式。. 若沒有指定SelectionLanguage屬性值為XPath則要注意以下情況:見:我的另外一篇關于如何使用XSLT的一個小示范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>
?
返回結果
<ul>???? <li>Microsoft Visual C# 2008 Step by Step </li>?
??? <li>Professional C# 2008 </li>?
</ul>
本文轉自左正博客園博客,原文鏈接:http://www.cnblogs.com/soundcode/p/3807167.html,如需轉載請自行聯(lián)系原作者 《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的XPath 详解,总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通用搜索引擎
- 下一篇: 从 JavaScript 到 TypeS