XPath的概念:
XPath是一種定位XML文檔的各個部分的語言,它還提供處理字符串,數字和布爾值的常用函數。XPath可以定位XML文檔的元素和屬性等部件。XPath提供的一星兒函數能夠定位返回字符串或檢測出字符串的長度,XPath還包括字符數據轉換成數字類型和布爾類型的函數。
XPath從它的路徑符號給出名稱,它使用的語法銅URL類似,通常稱XPath語句為XPath表達式。
XPath不是一種獨立技術,它用于其它的技術如XSLT中,用XPath可以檢索XML的元素和屬性,可以XPath看做是XML的SQL。
XPath語法:
1.定位路徑:他是一種選擇節點集合的XPath表達式類型,通常使用“/”隔開的定位階來構造定位路徑。如/games/game,上述定位路徑有兩個定位階。定位路徑有兩種類型:相對的和絕對的。相對的定位路徑是由“/”分開的一個或多個定位階的序列。絕對定位路徑由“/”和后面的相對定位路徑組成。
2.定位階:他是定位路徑的組成部分,由三部分組成:
1)一個軸:它規定了上下文節點和定位階所選節點之間的關系。
2)一個節點測試:它規定了定位階選擇的階段類型。
3)零或多個謂詞,它們使用了表達式進一步改進節點的選擇。
如XPath表達式"/games/game[@genre='rpg']",該表達式選擇了所有genre屬性值為rpg的位于games元素下的game元素。
3.節點測試:它通知XPath表達式運算的節點類型,節點測試通常都是源樹種元素名稱,如/games/game,該表達式有兩個節點測試:games和game。
4.軸說明符:它用于明確指出要處理的節點測試的關系,如果要選games元素的所有子元素,則代碼如下:child::games.
下面歸納了部分軸說明符
軸說明符 說明
child 節點的所有子節點
descendant 節點的所有后代節點
parent 節點的父節點
following-sibling 節點后面的兄弟節點
preceding-sibling 節點前面的兄弟節點
5.謂詞:它是另一種進一步縮小節點選擇范圍的方法。XPath使用方括號[]來指定謂詞,謂詞使用XPath提供的函數提供測試,它可以訪問屬性(使用@符號)。
如前面出現過的XPath表達式"/games/game[@genre='rpg']",方括號[]中的“@genre='rpg'”就是謂詞,該表達式用于測試位于games元素下的game元素的genre屬性值是否為rpg。
XPath函數:
XPath函數使得用戶能夠處理字符串,數字和節點集合,下面列出了三個節點集合函數:
number last() 返回最后位置 如count(games/game)返回games元素下的game元素數目
number position() 返回當前位置 如games/game[last()]返回games元素下的最后一個game元素
number count(node-set) 返回結合參數中節點數目 如/games/game[position()=1]將返回games元素下的首個game元素。
下面使用開源包dom4j對XML文檔進行XPath操作的例子:
將要處理的XML文檔如下:
<?xml version="1.0" encoding="GBK"?>
<employees>
<employee lable="tech">
<id>0001</id>
<name>李白</name>
<title>程序員</title>
<skill>Java</skill>
<age>18</age>
</employee>
<employee lable="tech">
<id>0002</id>
<name>杜甫</name>
<title>高級程序員</title>
<skill>C#</skill>
<age>28</age>
</employee>
<employee lable="tech">
<id>0003</id>
<name>Andy</name>
<title>項目經理</title>
<skill>PPT</skill>
<age>38</age>
</employee>
<employee lable="admin">
<id>0004</id>
<name>Bill</name>
<title>部門經理</title>
<skill>Java</skill>
<age>48</age>
</employee>
<employee lable="admin">
<id>0005</id>
<name>Cindy</name>
<title>總經理</title>
<skill>C#</skill>
<age>58</age>
</employee>
</employees>
XPath示例程序:
package com.heyang;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/**
* dom4j的XPath解析示例
* @author: 何楊(heyang78@gmail.com)
* @date: 2009-9-27-上午09:59:52
*/
public class XPathSample{
public static void main(String[] args) throws Exception{
SAXReader reader = new SAXReader();
Document doc = reader.read(XPathSample.class.getResource("/Employee.xml").getPath());
// 1.XPath選擇器,選擇根節點employees下所有屬性lable為tech的employee子節點
System.out.println("1.選擇根節點employees下所有屬性lable為tech的employee子節點");
XPath xpathSelector = DocumentHelper.createXPath("/employees/employee[@lable='tech']");
List results = xpathSelector.selectNodes(doc);
for ( Iterator iter = results.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
// 找到employee子節點的name子節點的文字打印
System.out.println(element.selectSingleNode("./name").getText());
}
// 2.打印名稱為李白的employee節點的title
System.out.println("2.打印名稱為李白的employee節點的title");
String title = doc.valueOf( "//employee[name='李白']/title" );
System.out.println(title);
// 3.XPath選擇器,選擇所有屬性lable為admin的employee子節點的name子節點
System.out.println("3.選擇所有屬性lable為admin的employee子節點的name子節點");
XPath xpathSelector2 = DocumentHelper.createXPath("//employee[@lable='admin']/name");
List results2 = xpathSelector2.selectNodes(doc);
for ( Iterator iter = results2.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
System.out.println(element.getText());
}
// 4.XPath選擇器,選擇所有年齡節點大于20的employee子節點的name子節點
System.out.println("4.選擇所有年齡節點大于20的employee子節點的name子節點");
XPath xpathSelector3 = DocumentHelper.createXPath("//employee[age>20]/name");
List results3 = xpathSelector3.selectNodes(doc);
for ( Iterator iter = results3.iterator(); iter.hasNext(); ) {
Element element = (Element) iter.next();
System.out.println(element.getText());
}
}
}
控制臺輸出:
1.選擇根節點employees下所有屬性lable為tech的employee子節點
李白
杜甫
Andy
2.打印名稱為李白的employee節點的title
程序員
3.選擇所有屬性lable為admin的employee子節點的name子節點
Bill
Cindy
4.選擇所有年齡節點大于20的employee子節點的name子節點
杜甫
Andy
Bill
Cindy
XPath相關參照文檔(網絡上搜索得到,不保證內容的完全正確性):
表達式 描述
節點名 選擇所有該名稱的節點集
/ 選擇根節點
// 選擇當前節點下的所有節點
. 選擇當前節點
.. 選擇父節點
@ 選擇屬性
示例
表達式 描述
bookstore 選擇所有bookstore子節點
/bookstore 選擇根節點bookstore
bookstore/book 在bookstore的子節點中選擇所有名為book的節點
//book 選擇xml文檔中所有名為book的節點
bookstore//book 選擇節點bookstore下的所有名為book為節點
//@lang 選擇所有名為lang的屬性
方括號[],用來更進一步定位選擇的元素
表達式 描述
/bookstore/book[1] 選擇根元素bookstore的book子元素中的第一個(注意: IE5以上瀏覽器中第一個元素是0)
/bookstore/book[last()] 選擇根元素bookstore的book子元素中的最后一個
/bookstore/book[last()-1] 選擇根元素bookstore的book子元素中的最后第二個
/bookstore/book[position()<3] 選擇根元素bookstore的book子元素中的前兩個
//title[@lang] 選擇所有擁有屬性lang的titile元素
//title[@lang='eng'] 選擇所有屬性值lang為eng的title元素
/bookstore/book[price>35.00] 選擇根元素bookstore的book子元素中那些擁有price子元素且值大于35的
/bookstore/book[price>35.00]/title 選擇根元素bookstore的book子元素中那些擁有price子元素且值大于35的title子元素
選擇位置的節點
通配符 描述
* 匹配所有元素
@* 匹配所有屬性節點
node() 匹配任何類型的節點
示例
表達式 描述
/bookstore/* 選擇根元素bookstore的下的所有子元素
//* 選擇文檔中所有元素
//title[@*] 選擇所有擁有屬性的title元素
使用操作符“|”組合選擇符合多個path的表達式