首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

XPath 完整指南:語法詳解與 Java 實戰應用

     編輯:Java 相關知識

前言

XPath (XML Path Language) 是在 XML 文檔中查找信息的語言,提供了強大的節點選擇、條件過濾、軸導航等能力。本文系統整理 XPath 核心語法、七大節點類型、常用運算符、函數庫,並結合 Java javax.xml.xpath 包給出完整實戰代碼,涵蓋命名空間處理、自定義函數/變量解析器等進階主題。

一、XPath 七大節點類型

類型說明
元素節點XML 元素,如 <book>
屬性節點元素屬性,如 lang="eng"
文本節點元素內的文本內容
命名空間節點XMLNS 宣告
處理指令節點 格式指令
註釋節點<!-- comment -->
文檔節點(根節點)整個 XML 文檔的頂層容器

二、核心路徑表達式速查表

表達式含義示例結果
nodename選擇當前節點的所有子節點bookstore 選所有 bookstore 子節點
/從根節點選擇/bookstore 選根元素 bookstore
//從任意位置選擇匹配節點//book 選文檔中所有 book
.選擇當前節點-
..選擇父節點-
@選擇屬性//@lang 選所有 lang 屬性

三、謂語 — 精準過濾節點

用方括號 [] 包裹條件:

  • /bookstore/book[1] — 第一個 book
  • /bookstore/book[last()] — 最後一個 book
  • //title[@lang='eng'] — lang="eng" 的 title
  • /bookstore/book[price>35.00]/title — 價格>35 的 book 的 title

四、通配符與多路徑選擇

通配符說明
*匹配任意元素節點
@*匹配任意屬性節點
node()匹配任意類型節點
|合併多個路徑結果

示例://book/title | //book/price 同時選取所有 title 和 price。

五、軸 — 樹關係導航

語法:axis::node-test[predicate]。常用軸:

  • child::book — 子元素 book
  • attribute::lang — lang 屬性
  • descendant::book — 所有後代 book
  • ancestor::book — 所有祖先 book
  • following::* — 文檔中當前節點結束標籤後的所有節點
  • preceding-sibling::* — 當前節點前的所有同級節點

六、運算符與函數

支持算術(+ - * div mod)、比較(= != < <= > >=)、邏輯(and or)、節點集合併(|)。內置函數如 count()、contains()、starts-with()、substring()、string-length() 等。

七、Java 中使用 XPath 完整實戰

1. 基礎 API 流程

// 1. 創建 XPath 對象
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

// 2. 編譯表達式
XPathExpression expr = xpath.compile("//name/text()");

// 3. 解析 XML 文檔
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false); // 無命名空間時
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new File("test.xml"));

// 4. 執行查詢並指定返回類型
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

// 5. 遍歷結果
for (int i = 0; i < nodes.getLength(); i++) {
    System.out.println(nodes.item(i).getNodeValue());
}

2. XPath 數據類型與 Java 映射

若不指定返回類型,evaluate(obj) 默認返回 String。

3. 命名空間處理 — 關鍵難點

XML 帶命名空間時,XPath 必須通過 NamespaceContext 註冊前綴:

// 自定義 NamespaceContext
class CustomNamespaceContext implements NamespaceContext {
    public String getNamespaceURI(String prefix) {
        if ("ns".equals(prefix)) return "https://www.example.com/ns";
        if ("tg".equals(prefix)) return "https://www.example.com/tg";
        if ("df".equals(prefix)) return "https://www.example.com/default";
        return XMLConstants.NULL_NS_URI;
    }
    public String getPrefix(String uri) { return null; }
    public Iterator getPrefixes(String uri) { return null; }
}

// 使用
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new CustomNamespaceContext());
XPathExpression expr = xpath.compile("//df:computer"); // 使用註冊前綴
NodeList list = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

注意:即使元素使用默認命名空間(無前綴),查詢時也必須為其分配一個前綴(如 df),否則無法匹配。

4. 進階:自定義函數解析器與變量解析器

通過實現 XPathFunctionResolver 和 XPathVariableResolver 接口,可在 XPath 表達式中調用 Java 方法或使用外部變量:

xpath.setXPathFunctionResolver(new XPathFunctionResolver() {
    public XPathFunction resolveFunction(QName name, int arity) {
        if ("my:custom-func".equals(name.getLocalPart())) {
            return args -> { /* 自定義邏輯 */ return "result"; };
        }
        return null;
    }
});

xpath.setXPathVariableResolver(new XPathVariableResolver() {
    public Object resolveVariable(QName name) {
        if ("myVar".equals(name.getLocalPart())) return "external-value";
        return null;
    }
});

八、完整示例代碼

import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;

public class XpathCompleteDemo {
    public static void main(String[] args) throws Exception {
        // 解析 XML
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // 必須開啟以支持命名空間
        Document doc = factory.newDocumentBuilder().parse(new File("books.xml"));

        XPathFactory xf = XPathFactory.newInstance();
        XPath xpath = xf.newXPath();

        // 1. 簡單查詢
        NodeList titles = (NodeList) xpath.evaluate("//book/title/text()", doc, XPathConstants.NODESET);
        for (int i = 0; i < titles.getLength(); i++) {
            System.out.println("Title: " + titles.item(i).getNodeValue());
        }

        // 2. 條件查詢
        Double price = (Double) xpath.evaluate("//book[price>35]/price", doc, XPathConstants.NUMBER);
        System.out.println("First price > 35: " + price);

        // 3. 命名空間查詢(需配合 NamespaceContext)
        // xpath.setNamespaceContext(new CustomNamespaceContext());
        // NodeList nsNodes = (NodeList) xpath.evaluate("//ns:book", doc, XPathConstants.NODESET);
    }
}

總結

XPath 是 XML 處理的瑞士軍刀,掌握其路徑表達式、軸導航、謂語過濾、命名空間處理,配合 Java 標準 API,能高效完成複雜 XML 查詢與轉換任務。實戰中重點注意:開啟 NamespaceAware、正確註冊命名空間前綴、指定精確返回類型,避免類型轉換異常。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
XPath 類型Java 類型XPathConstants 常量
node-setorg.w3c.dom.NodeListNODESET
numberjava.lang.DoubleNUMBER
booleanjava.lang.BooleanBOOLEAN
stringjava.lang.StringSTRING