一、基本介紹
XPath 是一門在 XML 文檔中尋找資訊的語言, 可用來在 XML 文檔中對元素和屬性進行遍曆。XPath 是 W3C XSLT 標準的主要元素,並且 XQuery 和 XPointer 同時被構建於 XPath 表達之上。因此,對 XPath 的理解是很多進階 XML 應用的基礎。XPath非常類似對資料庫操作的SQL語言,或者說JQuery,它可以方便開發人員抓起文檔中需要的東西。(dom4j也支援xpath)
二、節點類型
所謂節點(node),就是XML檔案的最小構成單位,一共分成7種。
- element(元素節點)
- attribute(屬性節點)
- text (文本節點)
- namespace (名稱空間節點)
- processing-instruction (處理命令節點)
- comment (注釋節點)
- root (根節點) 三、 常用路徑運算式
| 運算式 |
描述 |
| 節點名稱(nodename) |
選取此節點的所有子節點 |
| / |
從根節點選取 |
| // |
從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置 |
| . |
選取當前節點 |
| .. |
選取當前節點的父節點 |
| @ |
選取屬性 |
萬用字元
| |
描述 |
| * |
匹配任何元素節點 |
| @* |
匹配任何屬性節點 |
| node() |
匹配任何類型的節點 |
| | |
選取若干路徑 |
四、樣本
demo.xml
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Java Tutorials and Examples 2</title><language>en-us</language><item><title><![CDATA[Java Tutorials 2]]></title><link>http://www.javacodegeeks.com/</link></item><item><title><![CDATA[Java Examples 2]]></title><link>http://examples.javacodegeeks.com/</link></item></channel><college name="c1"><class name="class1"><student name="stu1" sex='male' age="21" /><student name="stu2" sex='female' age="20" /><student name="stu3" sex='female' age="20" /></class></college><bookstore><book><title lang="eng">Harry Potter</title><price>29.99</price></book><book><title lang="eng">Learning XML</title><price>39.95</price></book></bookstore></rss>
[例1] bookstore :選取 bookstore 元素的所有子節點。
[例2] /bookstore :選取根節點bookstore,這是絕對路徑寫法。
[例3] bookstore/book :選取所有屬於 bookstore 的子項目的 book元素,這是相對路徑寫法。
[例4] //book :選擇所有 book 子項目,而不管它們在文檔中的位置。
[例5] bookstore//book :選擇所有屬於 bookstore 元素的後代的 book 元素,而不管它們位於 bookstore 之下的什麼位置。
[例6] //@lang :選取所有名為 lang 的屬性。
帶條件的過濾:所有的條件,都寫在方括弧"[]"中,表示對節點進行進一步的篩選。
[例7] /bookstore/book[1] :表示選擇bookstore的第一個book子項目。
[例8] /bookstore/book[last()] :表示選擇bookstore的最後一個book子項目。
[例9] /bookstore/book[last()-1] :表示選擇bookstore的倒數第二個book子項目。
[例10] /bookstore/book[position()<3] :表示選擇bookstore的前兩個book子項目。
[例11] //title[@lang] :表示選擇所有具有lang屬性的title節點。
[例12] //title[@lang='eng'] :表示選擇所有lang屬性的值等於"eng"的title節點。
[例13] /bookstore/book[price] :表示選擇bookstore的book子項目,且被選中的book元素必須帶有price子項目。
[例14] /bookstore/book[price>35.00] :表示選擇bookstore的book子項目,且被選中的book元素的price子項目值必須大於35。
[例15] /bookstore/book[price>35.00]/title :表示在例14結果集中,選擇title子項目。
[例16] /bookstore/book/price[.>35.00] :表示選擇值大於35的"/bookstore/book"的price子項目。 [例17] //* :選擇文檔中的所有元素節點。
[例18] /*/* :表示選擇所有第二層的元素節點。
[例19] /bookstore/* :表示選擇bookstore的所有元素子節點。
[例20] //title[@*] :表示選擇所有帶有屬性的title元素。
[例21] //book/title | //book/price :表示同時選擇book元素的title子項目和price子項目。
五、java中實現xpath過濾的代碼:
import java.io.File;import java.io.FileInputStream;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.xpath.XPath;import javax.xml.xpath.XPathConstants;import javax.xml.xpath.XPathExpressionException;import javax.xml.xpath.XPathFactory;import org.w3c.dom.Document;import org.w3c.dom.Node;import org.w3c.dom.NodeList;public class XPathDemo {private static Document doc;private static XPath xpath;public static void main(String[] args) throws Exception {init();getRootEle();getChildEles();getPartEles();haveChildsEles();getLevelEles();getAttrEles();//列印根節點下的所有元素節點System.out.println(doc.getDocumentElement().getChildNodes().getLength());NodeList nodeList = doc.getDocumentElement().getChildNodes();for (int i = 0; i < nodeList.getLength(); i++) {if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {System.out.print(nodeList.item(i).getNodeName() + " ");}}}// 初始化Document、XPath對象public static void init() throws Exception {// 建立Document對象DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setValidating(false);DocumentBuilder db = dbf.newDocumentBuilder();doc = db.parse(new FileInputStream(new File("demo.xml")));// 建立XPath對象XPathFactory factory = XPathFactory.newInstance();xpath = factory.newXPath();}// 擷取根項目// 運算式可以更換為/*,/rsspublic static void getRootEle() throws XPathExpressionException {Node node = (Node) xpath.evaluate("/rss", doc, XPathConstants.NODE);System.out.println(node.getNodeName() + "--------"+ node.getNodeValue());}// 擷取子項目並列印public static void getChildEles() throws XPathExpressionException {NodeList nodeList = (NodeList) xpath.evaluate("/rss/channel/*", doc,XPathConstants.NODESET);for (int i = 0; i < nodeList.getLength(); i++) {System.out.print(nodeList.item(i).getNodeName() + " ");}System.out.println();}// 擷取部分元素// 只擷取元素名稱為title的元素public static void getPartEles() throws XPathExpressionException {NodeList nodeList = (NodeList) xpath.evaluate("//*[name() = 'title']",doc, XPathConstants.NODESET);for (int i = 0; i < nodeList.getLength(); i++) {System.out.print(nodeList.item(i).getNodeName() + "-->"+ nodeList.item(i).getTextContent());}System.out.println();}// 擷取包含子節點的元素public static void haveChildsEles() throws XPathExpressionException {NodeList nodeList = (NodeList) xpath.evaluate("//*[*]", doc,XPathConstants.NODESET);for (int i = 0; i < nodeList.getLength(); i++) {System.out.print(nodeList.item(i).getNodeName() + " ");}System.out.println();}// 擷取指定層級的元素public static void getLevelEles() throws XPathExpressionException {NodeList nodeList = (NodeList) xpath.evaluate("/*/*/*/*", doc,XPathConstants.NODESET);for (int i = 0; i < nodeList.getLength(); i++) {System.out.print(nodeList.item(i).getNodeName() + "-->"+ nodeList.item(i).getTextContent() + " ");}System.out.println("-----------------------------");}// 擷取指定屬性的元素// 擷取所有大於指定價格的書箱public static void getAttrEles() throws XPathExpressionException {NodeList nodeList = (NodeList) xpath.evaluate("//bookstore/book[price>35.00]/title", doc,XPathConstants.NODESET);for (int i = 0; i < nodeList.getLength(); i++) {System.out.print(nodeList.item(i).getNodeName() + "-->"+ nodeList.item(i).getTextContent() + " ");}System.out.println();}}
參考文檔:
https://my.oschina.net/cloudcoder/blog/223359
http://www.ruanyifeng.com/blog/2009/07/xpath_path_expressions.html