PHP xpath()函数讲解
在PHP的XML与HTML文档处理场景中,xpath()函数是DOMXPath类的核心方法,它基于XPath语法实现文档节点的精准查询,能够替代繁琐的遍历操作,快速定位到目标节点。本文将详细介绍该函数的用法、参数及实际应用场景。
一、xpath()函数基础说明
xpath()是PHP内置DOMXPath类的成员方法,用于在给定的DOM文档中执行XPath查询,返回匹配的节点集合。其语法定义如下:
public DOMXPath::xpath(string $expression): DOMNodeList|false
参数说明:
$expression:必填参数,类型为字符串,是符合XPath 1.0规范的查询表达式,用于定义节点的匹配规则。
返回值:
如果查询成功,返回
DOMNodeList对象,包含所有匹配到的节点;如果表达式语法错误,返回
false。
二、使用前提:创建DOMXPath实例
在调用xpath()之前,需要先构造DOMDocument对象加载目标文档,再基于该对象创建DOMXPath实例。以下是基础准备流程:
<?php // 1. 创建DOMDocument对象 $dom = new DOMDocument(); // 2. 加载XML或HTML文档,这里以XML为例 $xmlContent = '<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book category="编程"> <title>PHP核心编程</title> <author>张三</author> <price>89.90</price> </book> <book category="文学"> <title>乡土中国</title> <author>费孝通</author> <price>39.00</price> </book> </bookstore>'; $dom->loadXML($xmlContent); // 3. 创建DOMXPath实例,绑定到当前DOM文档 $xpath = new DOMXPath($dom); ?>
如果是处理HTML文档,可以使用loadHTML()或loadHTMLFile()方法加载,其余流程一致。
三、常用XPath表达式与xpath()调用示例
1. 查询所有指定标签的节点
若要获取文档中所有的<book>节点,表达式可以直接写标签名:
<?php
// 查询所有book节点
$books = $xpath->xpath('//book');
if ($books !== false) {
echo "共找到" . $books->length . "本书<br/>";
foreach ($books as $book) {
echo "节点名称:" . $book->nodeName . "<br/>";
}
}
?>这里的//book表示匹配文档中所有层级下的<book>节点,无论其嵌套位置。
2. 按属性筛选节点
若要筛选category属性为“编程”的<book>节点,可以使用属性匹配语法:
<?php
// 查询category为编程的book节点
$programBooks = $xpath->xpath('//book[@category="编程"]');
if ($programBooks !== false) {
foreach ($programBooks as $book) {
// 获取子节点title的内容
$titles = $xpath->xpath('title', $book); // 第二个参数指定查询上下文节点
if ($titles->length > 0) {
echo "编程类书籍:" . $titles->item(0)->nodeValue . "<br/>";
}
}
}
?>表达式//book[@category="编程"]中,@category表示取节点的category属性,[@category="编程"]是属性筛选条件。
3. 查询节点的文本内容
如果需要直接获取<price>节点的文本值,可以结合text()函数:
<?php
// 查询所有price节点的文本内容
$prices = $xpath->xpath('//price/text()');
if ($prices !== false) {
foreach ($prices as $price) {
echo "书籍价格:" . $price->nodeValue . "<br/>";
}
}
?>4. 多层节点路径查询
若要获取所有书籍的作者名称,可以按照节点层级编写表达式:
<?php
// 查询所有book下的author节点
$authors = $xpath->xpath('/bookstore/book/author');
if ($authors !== false) {
echo "所有作者:<br/>";
foreach ($authors as $author) {
echo $author->nodeValue . "<br/>";
}
}
?>这里的/bookstore/book/author是绝对路径,从根节点<bookstore>开始逐层匹配。
四、注意事项
XPath表达式严格区分大小写,标签名、属性名需要与文档中的实际名称完全一致。
如果加载的是HTML文档,部分不规范的标签可能导致解析异常,可先使用
libxml_use_internal_errors(true)屏蔽解析错误。DOMNodeList是动态集合,遍历过程中如果文档结构被修改,可能会影响遍历结果,建议先转换为数组再操作。当查询无匹配结果时,
xpath()返回的是长度为0的DOMNodeList对象,而非false,只有表达式语法错误时才会返回false,需要做区分判断。
五、实际应用场景
xpath()函数常用于以下场景:
爬取网页时解析HTML文档,提取目标内容,例如抓取https://www.ipipp.com的商品列表信息。
处理接口返回的XML格式数据,快速提取指定字段。
批量修改XML配置文件中的特定节点内容,无需逐层遍历。
通过合理运用XPath语法配合xpath()函数,可以大幅降低XML/HTML文档的处理复杂度,提升开发效率。