XPath是一门在XML文档中查找信息的语言,通过XPath可以快速定位到XML文档中的指定节点,不需要逐层遍历整个文档结构,大幅提升了XML数据解析的效率。不管是简单的标签查询还是复杂的多条件筛选,XPath都能轻松实现。
XPath基础语法
XPath使用路径表达式来选取XML文档中的节点,常见的路径表达式有以下几种:
- nodename:选取此节点的所有子节点
- /:从根节点开始选取
- //:从匹配选择的当前节点开始选择文档中的节点,不考虑它们的位置
- .:选取当前节点
- ..:选取当前节点的父节点
- @:选取属性
常用节点查询场景
查询指定标签的所有节点
如果要查询XML中所有名为book的节点,可以直接使用标签名作为路径表达式。以下是示例XML内容:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title>XML基础教程</title>
<price>59.9</price>
</book>
<book>
<title>XPath实战指南</title>
<price>69.9</price>
</book>
</bookstore>
对应的XPath表达式为//book,会返回所有book节点。
查询带特定属性的节点
如果要查询分类为编程的book节点,可以使用谓语条件,表达式写为//book[@category='编程']。以下是带属性的XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title>XML基础教程</title>
</book>
<book category="文学">
<title>散文精选</title>
</book>
</bookstore>
查询特定层级的节点
如果需要查询根节点下直接子节点的title,可以使用/bookstore/book/title表达式,只会匹配bookstore下一级book里的title节点,不会匹配更深层的同名节点。
XPath查询实用技巧
使用通配符简化查询
*通配符可以匹配任意节点,@*可以匹配任意属性。比如//book/*会匹配所有book节点的子节点,//book[@*]会匹配所有带任意属性的book节点。
使用谓语筛选位置
谓语写在方括号里,可以用来筛选特定位置的节点。比如//book[1]选取第一个book节点,//book[last()]选取最后一个book节点,//book[position()<3]选取前两个book节点。
多条件组合查询
可以使用and和or组合多个条件,比如//book[@category='编程' and price>60]会查询分类为编程且价格大于60的book节点。
不同语言中XPath查询示例
Python中使用XPath查询XML
Python可以借助lxml库实现XPath查询,示例代码如下:
from lxml import etree
# 解析XML内容
xml_content = """<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title>XML基础教程</title>
<price>59.9</price>
</book>
<book category="编程">
<title>XPath实战指南</title>
<price>69.9</price>
</book>
</bookstore>"""
root = etree.fromstring(xml_content.encode('utf-8'))
# 查询所有编程类的book节点
result = root.xpath("//book[@category='编程']/title/text()")
print(result) # 输出:['XML基础教程', 'XPath实战指南']
Java中使用XPath查询XML
Java可以使用内置的javax.xml.xpath包实现XPath查询,示例代码如下:
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 {
String xml = "<?xml version="1.0" encoding="UTF-8"?>" +
"" +
"XML基础教程 " +
"散文精选 " +
" ";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new java.io.ByteArrayInputStream(xml.getBytes("UTF-8")));
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//book[@category='编程']/title", doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getTextContent());
}
// 输出:XML基础教程
}
}