Xpath

概述

XPath在設計之初主要用於XSLT和XPointer(用於Xlink,還未普及),隨着XSLT 2.0的發佈,已經發展到XPath 2.0(06年6月),併成爲XSLT 2.0和XQuery 2.0的基礎
XPath以“路徑”方式查詢XML文檔,XPath表達式的基本形式是“/結點/子結點/二級子結點”,從左到右(即從外至內)匹配XML文檔的結點
XPath表達式分爲定位表達式和求值表達式。定位表達式用於匹配XML文檔的結點,而求值表達式則返回定位結果數值(字符串、布爾值、數值等)
XML文檔的模型
對於良構的XML文檔,有三種模型表示:
XPath數據模型:把XML文檔的多數內容表示爲一棵結點樹,樹的根結點代表文檔本身,其他結點有元素結點、屬性結點、文本結點、名稱空間結點、註釋結點等。XML聲明、DOCTYPE等不能表示爲結點
DOM:採用樹形層次結構表示XML文檔
XML信息表(Infoset):把XML文檔看作由信息項組成的一棵樹,每個信息項相當於XPath的一個結點,信息項可有若干屬性,屬性值表示信息項的特性

基本概念
層次結構
 XPath表達式以“/”分隔表示分層結構
XPath表達式最左邊的“/”表示從根結點開始
XPath表達式中間出現的“/”用於分隔上下兩層結構,表示父子關係
串聯的若干“/”分隔的部分形成先代(Ancestor)、後代(Descendant)關係

線性結構
 同屬一個父結點的結點間形成線性的兄弟(Sibling)關係
兄弟之間有先後,前面的是後面的“前導(Preceding)兄弟”,後面的是前面的“後繼(Following)兄弟”
可以用position()函數獲取結點在線性結構中的位置

XPath定位操作返回的是結點列表
 XPath定位表達式返回的是匹配的結點的列表,不是返回值
 XPath求值表達式可以返回結點集

根結點不是根元素
 XPath的根結點與XML文檔結點對應,包含了文檔的所有內容,不是XML文檔的根元素,根元素是XML文檔包含其它元素的結點,是根結點的一個子結點(根結點的其它子結點包括XML聲明、 DOCTYPE、註釋等)

絕對定位和相對定位
 若XPath表達式以“/”開始,則對應爲絕對定位;否則爲相對定位

XPath的概念

XPath路徑的構造方法
 由於XML文檔是層次結構的,定位元素不可能像平面結構的關係數據庫可以根據主鍵一步到位,只能是分步漸進的,每個分步稱爲一個“定位步(location step)”
 XPath的路徑有兩種:
串聯定位:使用“/”分隔符連接多個定位步
 如:/我的電腦/硬盤/分區
 先定位根結點,然後是“我的電腦”,接着是“硬盤”,最後是“分區”
並聯定位:使用“|”分隔符連接多個定位步
 如:硬盤 | 內存
 在上下文結點的子結點中定位所有“硬盤”和“內存”結點
XPath表達式的上下文
在某結點下的XPath表達式的計算結果——結點列表構成上下文,該結點稱爲上下文結點(Context node)
XPath表達式的結點列表中包含的結點的數目稱爲該上下文的大小(Context Size)
在遍歷XPath的結點列表時,遍歷遊標所到達的結點,稱爲當前結點

定位步的組成

XPath的定位步由三部分組成,格式爲:

軸::結點測試[謂項]

其中“軸”和“謂項”部分可以省略
軸(Axis):表示從當前結點開始,向哪個方向開後匹配結點。XPath定義了13條軸
結點測試:表示匹配軸方向上的哪些結點
謂項(Predicate):表示匹配的條件,是在軸和結點測試基礎上的進一步篩選

軸和結點測試

13條軸


結點測試
 在XPath中,結點測試必須位於軸的後面或放在謂項中,而函數的返回值只能出現在謂項中
結點測試:不支持DTD的DOCTYPE、ENTITY等
 元素名稱 : 具有特定名稱的結點
名稱空間前綴:元素名稱 : 名稱空間
processing-instruction(“名稱") : 處理指令
node() : 任何類型的結點
* : 現節點下所有元素,具有任何名稱的結點
*/elem : 現節點下所有節點的子節點中爲elem的節點
@Prop : 屬性值
@* : 所有現節點的屬性
. : 現節點
.. : 現節點上級
elem[i] : 現節點下第i個叫做elem的元素
elem[posetion()=1] : 同上
elem/[@prop="somevalue"] : 現節點下,名字爲elem,具有prop的屬性,並且屬性值爲somevalue的那個元素
elem1|elem2 : 現節點下,名字爲elem1或elem2的元素
.//elem : 現節點下,可以跨越級別,所有的名字叫做elem的元素
elem1//elem2 : 現節點下,可以跨越級別,所有的名字叫做elem2,且elem2的上級中有人叫elem1,且elem1是現節點的子元素的元素
text() : 現節點的子元素中所有的文字節點
comment() : 註釋
函數:不能直接出現在軸的後邊或結點測試的後邊
contains(串1,串2) :包含檢查
id(結點集等) :返回具有id屬性的結點
name() :結點名稱
position() :當前結點在上下文中的位置
starts-with(串1,串2) :“串1”以“串2”開始
count() : count(PERSON[name='tom']) 計數
number() : select="number(book/price)" 轉成數字
substring(value,start,length) : select="substring(name,1,3)"
sum() : select="sum(//price)" 求和

謂項

謂項(Predicate)以一對方括號“[“和”]”爲標記,中間爲條件表達式,置於XPath中,構成篩選條件,格式爲:
   [值1 操作符 值2]
  若謂項條件不成立,則從XPath結點列表中剔除該結點
確定結點是否存在
謂項的格式爲:[結點測試]
例如:[姓名] 、[@姓名]
用關係表達式表示篩選條件
謂項格式爲:[值1 關係運算符  值2]
例如:[年齡>=“20”] 、 [@性別!=“男”]
關係元素符包括:=、!=、<、<=、>=、>
用布爾運算表示複合條件
謂項格式爲:[布爾值1  布爾運算符 布爾值2]
例如:[年齡=“20” and @性別=“女”]
布爾運算符包括:or(或)、and(與)
用數值表達式構造複雜運算
數值運算符包括: +、-、*、div(除)、mod(求模)、-(取反)

例如:

<?xml version="1.0" encoding="utf-8"?>
<學生名單>
	<班級 名稱="計算機1班">
		<學生 姓名="張三" 學號="101"/>
		<學生 姓名="李四" 學號="102"/>
		<學生 姓名="王五" 學號="103"/>
		<班長 學號="103">
			<電話 號碼="13512345678"/>
		</班長>
		<介紹>該班爲優良學風班</介紹>
	</班級>
	<班級 名稱="計算機2班">
		<學生 姓名="張三" 學號="201"/>
	</班級>
</學生名單>

實例1:假設上下文結點爲“/學生名單/班級”,XPath匹配結果分別爲:
學生                     所有學生結點
班長/電話            所有電話結點
..                           班級結點
../..                        學生名單結點
./介紹                   介紹結點
//學生                   所有學生結點
self::*//學生         當前結點下含有學生子結點的任意結點
/descendant::node() 根節點的所有後代結點
//node()               所有節點
.//node()              當前結點下的所有結點
“介紹”文本     介紹/text()
每個“學生”的“姓名”學生/@姓名

參照實例(1),假設上下文結點爲“學生名單”,寫出路徑的XPath:
有“班長”的所有班級                              班級[班長]
包含“電話”子結點的所有結點              班級/*[電話]
叫“張三”的“學生”                              班級/學生[@姓名="張三"]
“計算機1班”叫“張三”的“學生”    班級[@名稱="計算機1班"]/學生[@姓名="張三"]

名稱空間

結點的本地名稱可以用函數local-name()獲取 例如:  //*[local-name()=“學生”]
結點的名稱空間可用函數namespace-uri()獲取 例如:  //*[namespace-uri()=“myurn:computer”]
在XPath中使用名稱空間前綴限定名稱空間 例如:  //學籍管理:學生[@學籍管理:姓名=“張三”]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章