上次說到如果XML檔案的層次比較多,直接通過 getChild() 方法獲得元素將會是一件很痛苦的事情,用XPATH來處理就方便多了。JDOM從V1.0bata10版中,已經加入了對XPATH
的支援。(拖了好久,今天總算是補上了。)
XPATH基礎
XPATH遵循文件物件模型(DOM)的路徑格式,基本文法由運算式構成。在計算運算式的值之後產生一個對象,這種對象有以下四種基本類型:節點集合、布爾型、數字型和字串型。XPATH基本上和在檔案系統中尋找檔案類似,如果路徑是以"/"開頭的,就表明該路徑表示的是一個絕對路徑,這和在UNIX系統中關於檔案路徑的定義是一致的。以"//"開頭則表示在文檔中的任意位置尋找。
以範例XML文檔(friends.xml)為例來瞭解XPATH: <?xml version="1.0" encoding="UTF-8"?>
<friends comment="Friends List">
<friend number="1">
<name>zoof</name>
<sex value="male" />
<phone>87654321</phone>
</friend>
<friend number="2">
<name>joe</name>
<sex value="male" />
<phone>87654322</phone>
</friend>
<friend number="3">
<name>joe</name>
<sex value="female" />
<phone>87654323</phone>
</friend>
</friends> 在XML文檔中使用位置路徑運算式來尋找資訊,這些運算式有很多種組成方式。一般我們用得最多的恐怕是 節點元素 尋找。XPATH中用正斜杠(/)來分隔子結點,返回所有與模式相匹配的元素。下面以幾個 運算式 的例子來說明一下返回結果: 運算式:/friends/friend
返回:根項目friends下所有的 friend 元素(或節點)。 運算式:/friends/*
返回:根項目friends下所有的元素(或節點)。(“*”相當於萬用字元,表示“所有”的) 運算式://friend
返回:任意元素(或節點)下的所有 friend 元素(或節點)。(注意:不僅僅是1中 根項目friends下面的friend元素,如果存在的話) 運算式:/friends/friend[@number='1']
返回:根項目下元素名稱為 friend,number屬性為'1'的全部元素(或節點)。(對於元素或節點的附加元素,比如屬性,函數等都要用方括弧"[]"擴起來,屬性前面要加上"@"號) 運算式:/friends/friend/phone[text()='87654321']
返回:元素friends/friend下電話號碼為 87654321 的全部元素。(text()是XPATH的函數,功能是取出當前節點的常值內容,即content。) 運算式://name/parent::*
返回:name元素的所有父元素(或節點)。(parent::* 表示這個元素的所有的父節點的集合) 上面的介紹對於我們一般的應用基本上夠用了,如果你需要進一步的深入,請查看W3C發布的關於XAPH的官方資料。
JDOM+XPATH應用 現在我們開始使用XPATH結合JDOM來操作XML檔案了。JDOM的關於XPATH的api主要有一個類:Xpath.java,在org.jdom.xpath這個包中。這個類中的核心方法主要是兩個靜態方法:selectNodes()和selectSingleNode()。前者根據一個xpath語句返回一組節點:List;後者根據一個xpath語句返回合格第一個節點:Object。
public static List selectNodes(Object arg1,String arg2) throws org.jdom.JDOMException;
public static Object selectSingleNode(Object arg1,String arg2) throws org.jdom.JDOMException;
在使用XPATH之前,請先確定你的classpath路徑裡面有如下幾個JAR包,如果沒有,請從JDOM的發行包中lib目錄下copy:
saxpaht.jar
jaxen-core.jar
jaxen-jdom.jar樣列JAVA代碼:/*
* Created on 2004-11-17
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/ import java.io.IOException;
import java.util.List;import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Text;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;/**
* @author wanghua
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class XpathSample {
public static void main(String[] args) throws JDOMException, IOException{
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build("friends.xml");
Element root = doc.getRootElement();
List list = XPath.selectNodes(root,"/friends/friend");
System.out.println("[info] Friends List:");
for(int ii = 0; ii < list.size(); ii++){
Element element = (Element)list.get(ii);
String number = element.getAttributeValue("number");
String name =
( (Text) XPath.selectSingleNode(element,"//friend[@number='" + number + "']/name/text()")).getTextNormalize();
String sex =
((Element)XPath.selectSingleNode(element,"//friend[@number='" + number + "']/sex")).getAttributeValue("value");
String phone =
( (Text) XPath.selectSingleNode(element,"//friend[@number='" + number + "']/phone/text()")).getText();
System.out.println("No."+number);
System.out.println(" Name:[" + name + "]");
System.out.println(" Sex:[" + sex + "]");
System.out.println(" Phone:[" + phone + "]");
System.out.println();
}
System.out.println("[info] End of Friends List.");
}
}輸出結果:[info] Friends List:
No.1
Name:[zoof]
Sex:[male]
Phone:[87654321]No.2
Name:[joe]
Sex:[male]
Phone:[87654322]No.3
Name:[joe]
Sex:[female]
Phone:[87654323][info] End of Friends List. [參考資料]
薛穀雨(rainight@126.com):JDOM/XPATH編程指南