You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 8.4中使用Dom\HTMLDocument为何无法通过标签选择器查询元素?

PHP 8.4 Dom\HTMLDocument中XPath查询指定标签返回0的问题

尝试使用PHP 8.4新增的Dom\HTMLDocument类统计页面中所有div标签数量,编写代码后发现使用//div查询返回0个结果,但//*能找到包含div在内的6个元素。带类名的复杂选择器只要用*代替具体标签就能正常工作,代码如下:

<?php

$html = <<<HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Example</title>
</head>
<body>
    <div>Hello</div>
</body>
</html>
HTML;

$doc = Dom\HTMLDocument::createFromString($html);
$xpath = new Dom\XPath($doc);

// No divs found:
$divs = $xpath->query('//div');
echo $divs->count(); // 0

// 6 elements found, including the div:
$anyTags = $xpath->query('//*');
echo $anyTags->count(); // 6

问题出在HTML命名空间上。Dom\HTMLDocument会自动将所有HTML元素放入默认的HTML命名空间(http://www.w3.org/1999/xhtml),但默认创建的Dom\XPath实例不会自动识别这个命名空间,直接用标签名查询时会匹配不到命名空间内的元素。

解决方法

有两种可行的修复方式:

  1. 注册HTML命名空间并使用带前缀的XPath表达式
$doc = Dom\HTMLDocument::createFromString($html);
$xpath = new Dom\XPath($doc);
// 注册HTML命名空间,前缀设为html
$xpath->registerNamespace('html', 'http://www.w3.org/1999/xhtml');
// 使用带前缀的查询语法
$divs = $xpath->query('//html:div');
echo $divs->count(); // 输出1
  1. 使用local-name()匹配标签本地名称
    无需注册命名空间,直接通过元素的本地名称进行查询:
$divs = $xpath->query('//*[local-name()="div"]');
echo $divs->count(); // 输出1

第一种方法更规范,适合复杂的XPath查询场景;第二种方法更简洁,适合简单的标签查询需求。

内容的提问来源于stack exchange,提问作者Robo Robok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:24:54