XPath全称为XML Path Language,是W3C定义的标准查询语言,核心作用是在XML文档的树形结构中快速定位、查询目标节点,也可以应用于HTML文档的节点查找。它通过路径表达式来描述节点的位置,不需要遍历整个文档就能精准找到需要的内容,大幅提升了XML数据处理的效率。

XPath的基础概念
XML文档本身是一个树形结构,包含元素节点、属性节点、文本节点等多种类型。XPath把文档中的每个部分都看作一个节点,通过节点之间的关系(父、子、兄弟、祖先、后代)来构建定位路径。比如根节点是文档的起始点,元素节点的子节点可以是其他元素或者文本,属性节点则依附于元素节点存在。
XPath路径表达式语法
基础路径符号
- /:从根节点开始选择,比如
/bookstore表示选择根节点下的bookstore元素 - //:从当前节点选择文档中所有符合条件的后代节点,不管位置,比如
//book表示选择文档中所有的book元素 - .:选择当前节点
- ..:选择当前节点的父节点
- @:选择属性节点,比如
//book/@category表示选择所有book元素的category属性
节点筛选语法
可以通过方括号添加筛选条件,常见的筛选方式包括:
- 按位置筛选:
/bookstore/book[1]选择bookstore下的第一个book子元素,索引从1开始 - 按属性值筛选:
//book[@category='web']选择所有category属性值为web的book元素 - 按子元素值筛选:
//book[price>30]选择子元素price的值大于30的book元素
实战示例:定位XML节点
首先准备一个测试用的XML文档,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="web">
<title lang="en">XPath Tutorial</title>
<author>John Doe</author>
<price>29.99</price>
</book>
<book category="programming">
<title lang="zh">Python基础教程</title>
<author>Jane Smith</author>
<price>49.99</price>
</book>
<book category="web">
<title lang="en">CSS Guide</title>
<author>Bob Lee</author>
<price>35.00</price>
</book>
</bookstore>
以下是几个常见的XPath查询示例及对应的结果:
| XPath表达式 | 查询结果 |
|---|---|
| /bookstore/book[1]/title | 第一个book元素的title子元素,内容为XPath Tutorial |
| //book[@category='web'] | 所有category为web的book元素,共2个 |
| //title[@lang='zh'] | lang属性为zh的title元素,内容为Python基础教程 |
| /bookstore/book[price>30]/author | price大于30的book元素的author子元素,内容为Jane Smith和Bob Lee |
编程语言中调用XPath的示例
Python示例
Python中可以使用lxml库来解析XML并执行XPath查询,代码如下:
from lxml import etree
# 解析XML内容
xml_content = """<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="web">
<title lang="en">XPath Tutorial</title>
<author>John Doe</author>
<price>29.99</price>
</book>
<book category="programming">
<title lang="zh">Python基础教程</title>
<author>Jane Smith</author>
<price>49.99</price>
</book>
</bookstore>"""
root = etree.fromstring(xml_content.encode('utf-8'))
# 查询所有category为web的book的title文本
titles = root.xpath("//book[@category='web']/title/text()")
print(titles) # 输出 ['XPath Tutorial']
# 查询price大于30的book的author
authors = root.xpath("/bookstore/book[price>30]/author/text()")
print(authors) # 输出 ['Jane Smith']
Java示例
Java中可以使用JAXP自带的XPathFactory来执行查询,代码如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class XPathDemo {
public static void main(String[] args) throws Exception {
// 解析XML文档,这里以本地文件为例,也可以解析输入流
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("books.xml");
// 创建XPath对象
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
// 查询所有category为web的book的title
NodeList titleNodes = (NodeList) xpath.evaluate("//book[@category='web']/title", doc, XPathConstants.NODESET);
for (int i = 0; i < titleNodes.getLength(); i++) {
System.out.println(titleNodes.item(i).getTextContent());
}
}
}
常见注意事项
- XPath的索引从1开始,和很多编程语言的数组从0开始不同,使用时需要注意避免索引错误
- 如果XML文档有命名空间,需要在XPath中处理命名空间映射,否则可能无法定位到节点
- 路径表达式中的特殊字符比如尖括号、引号需要正确转义,避免语法错误
- 尽量使用精准的路径表达式,减少//的使用范围,可以提升查询效率