XPath是定位XML节点的路径表达式,需嵌入其他语言使用;XQuery是图灵完备查询语言,支持变量、函数、多文档处理和FLWOR等高级特性。

XPath 是表达式,XQuery 是查询语言
XPath 本身不是独立运行的语言,而是一套用于定位 XML 文档中节点的路径表达式语法,必须嵌入在其他语言(如 XSLT、XQuery、DOM API)中使用。XQuery 则是完整的图灵完备查询语言,能声明变量、写函数、做条件判断、连接多个文档,甚至支持 FLWOR 表达式(类似 SQL 的 for/let/where/order by/return)。
你在 document.evaluate()(浏览器 DOM)、xpath()(Python lxml)、或 XSLT 的 select 属性里写的,都是 XPath 表达式;而用 zorba、BaseX 或 Saxon 的 xquery() 方法执行的,才是 XQuery 脚本。
数据映射场景下,XPath 够用就别上 XQuery
多数 Web 抓取、配置提取、简单 XML 转 JSON 场景,只需要“从 XML 里捞出几个字段”,这时 //book/title/text() 这类 XPath 就足够了——它轻量、跨平台支持好、解析快,且几乎所有 XML/HTML 解析库都内置支持。
- 用 Python
lxml.etree时,root.xpath('//price')返回元素列表,直接取.text或.get('attr')即可映射到字典字段 - 在 JavaScript 中,
document.evaluate('//input[@type="hidden"]', doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)可批量提取表单隐藏域 - 若需补全缺失字段(比如没
就填"unknown"),XPath 本身做不到,得靠宿主语言(Python/JS)兜底处理
XQuery 真正起作用的地方:多源、结构重组、类型安全
当映射逻辑涉及合并多个 XML 文件、按业务规则重排嵌套结构、需要强类型转换(如把字符串日期转为 xs:date)、或输出格式必须严格符合另一个 Schema 时,XQuery 才显出不可替代性。
例如,把三个不同来源的订单 XML 合并成统一格式,并过滤掉 status = "cancelled" 的记录:
for $o in doc("orders1.xml")//order,
$o2 in doc("orders2.xml")//order,
$o3 in doc("orders3.xml")//order
let $all := ($o, $o2, $o3)
where $all/status != "cancelled"
return
{xs:decimal($all/total)}
{xs:date($all/date)}
这段代码依赖 XQuery 的文档加载(doc())、类型强制(xs:decimal)、以及 FLWOR 的聚合能力——XPath 完全无法完成。
容易踩的坑:别混淆 XPath 版本和 XQuery 引擎行为
同一个表达式在不同环境结果可能不同,根源常在于版本错配:
-
//node[1]在 XPath 1.0 中匹配“每个父节点下的第一个node”,在 XPath 2.0+(也是 XQuery 1.0+ 基础)中才表示“整个文档中第一个node”——很多旧系统默认只支持 1.0 - XQuery 引擎(如 BaseX)默认启用 XPath 2.0+ 函数(
replace()、tokenize()),但 Pythonlxml默认只支持 XPath 1.0,调用replace()会直接报Invalid expression - 命名空间处理差异极大:XPath 需显式注册前缀(
etree.XPathEvaluator(..., namespaces={'x': 'http://ns'})),XQuery 则用declare namespace x = "http://ns",漏写就会查不到任何节点
实际选型时,先确认目标平台支持的 XPath 版本和是否内置 XQuery 引擎;如果只是从 Spring Boot 的 @XPathParam 注解里取值,那永远只和 XPath 1.0 打交道——XQuery 再强大也用不上。










