XPath 在线测试器

针对 XML 测试 XPath 表达式,查看所有匹配节点

加载示例

XML 输入

本地运行 · 粘贴密钥安全无忧

什么是 XPath?

XPath(XML 路径语言)是一种用于从 XML 文档中选取节点的查询语言。XPath 由 W3C 作为 XSLT 标准的一部分定义,将 XML 文档视为节点树,并提供基于路径的语法来导航该树。例如,XPath 表达式 //book[@category="fiction"]/title 会选取所有 category 属性值为 "fiction" 的 book 元素下的 title 子元素。XPath 1.0 是所有主流浏览器和大多数 XML 库所支持的版本,于 1999 年作为 W3C 推荐标准发布,至今仍是部署最广泛的版本。

XPath 表达式返回四种结果类型之一:节点集、字符串、数字或布尔值。节点集是最常见的结果类型,包含零个或多个 XML 节点(元素、属性、文本节点、注释或处理指令)。字符串、数字和布尔值结果来自 XPath 函数,例如 count()、sum()、contains() 以及布尔比较。这套类型系统使 XPath 既适合提取数据,也适合在 XSLT 样式表和 XML Schema 断言中编写条件逻辑。

XPath 1.0 表达式在各处均可使用:JavaScript 的 document.evaluate()、Python 的 lxml 和 ElementTree、Java 的 javax.xml.xpath、PHP 的 DOMXPath,以及命令行工具 xmllint。XPath 2.0 和 3.1 提供了更丰富的类型系统和函数,但需要专用引擎(如 Saxon)。默认使用 XPath 1.0 即可。只有在需要序列、正则表达式或高阶函数时,才考虑使用 2.0 或 3.1,并接受对 Saxon 或 BaseX 的依赖。

为什么使用在线 XPath 测试器?

编写正确的 XPath 表达式需要理解文档结构并针对真实数据进行测试。本工具提供交互式环境,让你可以反复调试表达式,无需搭建项目或编写样板代码。

即时测试表达式
粘贴 XML,输入表达式,实时查看匹配节点。无需编译步骤,无需配置 REPL,也无需安装任何依赖。
🔒
隐私优先处理
所有 XML 解析和查询求值均在浏览器中通过原生 DOMParser 和 document.evaluate() API 完成。你的 XML 数据始终不会离开本机。
🔍
逐步调试复杂查询
通过逐一测试每个轴和谓词来拆解长表达式。查看每一步匹配的节点,精准定位错误所在。
📋
复制结果用于文档
一键复制匹配节点或标量结果。便于粘贴到问题报告、测试断言或数据提取脚本中。

XPath 测试器使用场景

前端开发
在将 XPath 选择器嵌入调用 document.evaluate() 的 JavaScript 代码之前,先测试用于 SVG 操作或基于 XML 的配置解析的 XPath 表达式。
后端工程
在用 Python、Java 或 Go 编写提取逻辑之前,先针对 SOAP 响应或 XML API 负载验证查询是否正确。
DevOps / 基础设施
查询 XML 配置文件(Maven pom.xml、Spring beans、CI 流水线配置),提取依赖版本或验证设置,无需修改文件。
质量保证 / 测试自动化
在将 XPath 定位器添加到测试脚本之前,先为 Selenium 或 Playwright 构建并验证这些定位器。测试缺少属性或命名空间前缀等边缘情况。
数据工程
在将查询接入 ETL 流水线之前,先对 XML 数据源(RSS、Atom、XBRL 财务报告)原型化测试查询逻辑。
学生 / 学习者
使用示例 XML 探索 XPath 轴、谓词和函数。立即查看结果,建立对树形遍历模式的直觉认知。

XPath 轴参考

轴定义了相对于当前(上下文)节点的导航方向。完整语法为 axis::node-test[predicate],但大多数开发者日常使用的是缩写形式(//、@、..)。下表列出了 XPath 1.0 的所有轴及实用示例。

示例说明
childchild::bookDirect children named "book"
descendantdescendant::titleAll "title" elements at any depth
parentparent::*The parent of the current node
ancestorancestor::catalogAll ancestors named "catalog"
following-siblingfollowing-sibling::bookSiblings after the current node
preceding-siblingpreceding-sibling::bookSiblings before the current node
attributeattribute::langThe "lang" attribute of the node
selfself::bookThe current node if it is "book"
descendant-or-self//titleShorthand: any "title" in the tree
ancestor-or-selfancestor-or-self::*Current node plus all ancestors

XPath 1.0 函数

XPath 1.0 定义了 27 个内置函数,分属四类:节点集、字符串、数字和布尔值。以下是编写查询时最常用的函数。所有函数均受本测试器及每个符合规范的实现支持。

函数类别说明
text()Node testSelects text content of a node
position()NumericReturns 1-based position in node set
last()NumericReturns size of current node set
count()NumericCounts nodes: count(//book)
contains()Stringcontains(@class, "active") — substring match
starts-with()Stringstarts-with(title, "The") — prefix match
normalize-space()StringStrips leading/trailing whitespace
string-length()NumericReturns character count of a string
sum()Numericsum(//price) — totals numeric values
not()Booleannot(@disabled) — negation
name()StringReturns element or attribute name

代码示例

以下示例展示了如何以编程方式求值 XPath 表达式。每段代码均使用相同的 catalog.xml 结构,便于对比各语言的 API 差异。

JavaScript (browser)
const xml = `<catalog>
  <book id="1"><title>1984</title><price>7.99</price></book>
  <book id="2"><title>Dune</title><price>12.99</price></book>
</catalog>`

const parser = new DOMParser()
const doc = parser.parseFromString(xml, 'application/xml')

// Select all book titles
const result = doc.evaluate('//book/title', doc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)
let node = result.iterateNext()
while (node) {
  console.log(node.textContent) // → "1984", "Dune"
  node = result.iterateNext()
}

// Get a numeric value
const sum = doc.evaluate('sum(//price)', doc, null, XPathResult.NUMBER_TYPE, null)
console.log(sum.numberValue) // → 20.98
Python (lxml)
from lxml import etree

xml = """<catalog>
  <book id="1"><title>1984</title><price>7.99</price></book>
  <book id="2"><title>Dune</title><price>12.99</price></book>
</catalog>"""

tree = etree.fromstring(xml.encode())

# Select elements by attribute
books = tree.xpath('//book[@id="1"]/title/text()')
print(books)  # → ['1984']

# Use predicates with position
first = tree.xpath('//book[1]/title/text()')
print(first)  # → ['1984']

# Boolean check
has_cheap = tree.xpath('boolean(//price[. < 10])')
print(has_cheap)  # → True
Java (javax.xml.xpath)
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.*;

var factory = DocumentBuilderFactory.newInstance();
var builder = factory.newDocumentBuilder();
var doc = builder.parse(new java.io.File("catalog.xml"));

var xpath = XPathFactory.newInstance().newXPath();

// Select node set
NodeList titles = (NodeList) xpath.evaluate(
    "//book/title", doc, XPathConstants.NODESET
);
for (int i = 0; i < titles.getLength(); i++) {
    System.out.println(titles.item(i).getTextContent());
    // → "1984", "Dune"
}

// Evaluate to number
double total = (double) xpath.evaluate(
    "sum(//price)", doc, XPathConstants.NUMBER
);
System.out.println(total); // → 20.98
CLI (xmllint)
# Select all book titles
xmllint --xpath '//book/title/text()' catalog.xml
# → 1984Dune

# Select by attribute
xmllint --xpath '//book[@id="2"]/title' catalog.xml
# → <title>Dune</title>

# Count nodes
xmllint --xpath 'count(//book)' catalog.xml
# → 2

# Using xmlstarlet for formatted output
xmlstarlet sel -t -v '//book/title' -n catalog.xml
# → 1984
# → Dune

常见问题

XPath 1.0 与 XPath 3.1 有什么区别?
XPath 1.0 有四种数据类型(节点集、字符串、数字、布尔值)和 27 个函数。XPath 3.1 新增了序列、映射、数组、日期/时间类型、正则表达式、高阶函数和 JSON 支持。浏览器和大多数标准库只实现了 1.0 版本。3.1 版本需要 Saxon 等专用引擎。
如何选取具有特定属性值的节点?
使用谓词,并用 @ 作为 attribute 轴的缩写。例如,//book[@category="fiction"] 选取所有 category 属性值为 "fiction" 的 book 元素。也可以组合多个谓词://book[@category="fiction"][@year > 2000]。
为什么我的 XPath 没有返回结果,即使 XML 中包含匹配元素?
最常见的原因是 XML 命名空间。如果你的 XML 声明了默认命名空间(xmlns="..."),即使没有前缀,元素也属于该命名空间。在 XPath 1.0 中,必须注册命名空间并在表达式中使用前缀。在浏览器 JavaScript 中,需将命名空间解析器作为第三个参数传递给 document.evaluate()。
XPath 能修改 XML 内容吗?
不能。XPath 是只读查询语言,只能选取和求值节点,无法插入、删除或更新节点。要修改 XML,需使用 XSLT 转换、DOM 操作方法,或 Python 的 lxml 等提供独立编辑 API 的库。
XPath 中双斜杠(//)是什么意思?
双斜杠是 descendant-or-self 轴的缩写。表达式 //title 表示「选取文档树中任意深度的所有 title 元素」。它等价于完整形式 /descendant-or-self::node()/title。在表达式开头使用 // 会搜索整个文档;在路径中间使用(如 /catalog//title)则搜索特定节点的所有后代。
如何选取文本内容而非元素节点本身?
在表达式末尾追加 /text()。例如,//book/title/text() 以字符串节点的形式返回每个 title 元素的文本内容,而非元素节点本身。在代码中,也可以直接访问返回元素节点的 .textContent 属性,而无需使用 text()。
查询 XML 时,XPath 比 CSS 选择器更快吗?
CSS 选择器针对 HTML 和浏览器中的 DOM 遍历进行了优化。XPath 的表达能力更强:它支持父节点遍历、兄弟轴、数字谓词以及 CSS 选择器无法表达的内置函数。对于 HTML,CSS 选择器(querySelector)通常更快。对于 XML,大多数服务端库只提供 XPath 接口,CSS 选择器根本不是可选项。