如何在 PHP 中从 DOMNodeList 中筛选指定标签名的节点
技术百科
花韻仙語
发布时间:2026-01-27
浏览: 次 domnodelist 本身不支持 getelementsbytagname() 方法,需通过遍历并检查 nodename 属性来实现标签过滤;本文详解错误原因、正确实现方式及更优的 xpath 替代方案。
在 PHP 的 DOM 扩展中,DOMNodeList 是一个只读的节点集合对象(类似数组),它不是 DOM 节点,因此不具备 getElementsByTagName() 这类属于 DOMElement 或 DOMDocument 的方法。你遇到的 Uncaught Error: Call to undefined method DOMNodeList::getElementsByTagName() 正源于此——$related_notions 是 DOMNodeList 实例,而 getElementsByTagName() 只能被调用在单个元素节点(如 DOMElement)或文档根节点上。
✅ 正确做法是:遍历 DOMNodeList,对每个节点单独判断其标签名。你提供的解决方案完全可行:
$index = new DOMDocument();
$index->load('index.xml');
$xpath = new DOMXpath($index);
$related_notions = $xpath->query("/index/notion[name='" . $name . "']/relations/*");
foreach ($related_notions as $item)
{
if ($item instanceof DOMElement && $item->nodeName === 'superordinate') {
// ✅ 安全执行操作(添加 instanceof 检查更健壮)
echo $item->textContent;
}
}⚠️ 注意事项:
- 建议添加 instanceof DOMElement 判断,避免因空白文本节点(DOMText)等非元素节点导致 nodeName 比较异常;
- 直接使用 ===(严格比较)而非 ==,防止类型隐式转换引发意外匹配;
- $name 变量需确保已过滤/转义,否则存在 XPath 注入风险(推荐使用 DOMXPath::evaluate() 配合参数绑定,或先用 htmlspecialchars() 处理,但更佳实践是预编译表达式 + bindValue —— 不过原生 DOM 扩展暂不支持参数绑定,建议改用 addNamespace() + 安全字符串拼接,或升级至支持 PDO 风格绑定的库如 symfony/dom-crawler)。
✨ 更优进阶方案:直接在 XPath 中完成筛选,语义清晰且性能更高(无需 PHP 层遍历):
立即学习“PHP免费学习笔记(深入)”;
// 一次性获取所有符合条件的 superordinate 元素
$superordinates = $xpath->query("/index/notion[name='" . $name . "']/relations/superordinate");
foreach ($superordinates as $item) {
// $item 已确定为 元素
echo $item->getAttribute('id') ?? 'no-id';
} ? 总结:
DOMNodeList 是结果集容器,不可调用节点方法;筛选应优先在 XPath 表达式中完成;若逻辑复杂必须后处理,则务必遍历 + nodeName 判断,并辅以类型校验。掌握这一机制,可显著提升 XML 解析代码的健壮性与可维护性。
# 是一个
# 这类
# 更高
# 这一
# 进阶
# 推荐使用
# 绑定
# 而非
# 不支持
# Error
# 对象
# 隐式转换
# html
# xml
# 字符串
# node
# lsp
# php
# 遍历
# dom
# symfony
# undefined
# pdo
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么关闭资讯和兴趣_Windows11任
- LINUX下如何配置VLAN虚拟局域网_在LINU
- Win10怎样安装Word样式库_Win10安装W
- 如何将文本文件中的竖排字符串转换为横排字符串
- Windows 10怎么把任务栏放在屏幕上方_Wi
- php本地部署后数据库连接报错_1045acces
- 如何使用Golang sort排序切片_Golan
- 获取 PHP 文件最后修改时间的正确方法
- Python 模块的 __name__ 属性如何由
- Win11怎么关闭防火墙通知_屏蔽Win11安全中
- 手机php怎么转mp4_手机端php文件转mp4a
- 如何理解Go指针和内存分配关系_Go Pointe
- Win11搜索栏无法输入_解决Win11开始菜单搜
- 如何使用Golang table-driven f
- 如何在Windows上设置闹钟和计时器_系统自带的
- Win11如何设置文件权限 Win11 NTFS文
- Python高性能计算项目教程_NumPyCyth
- Windows怎样关闭开始菜单推荐广告_Windo
- 如何使用Golang指针与接口结合_实现方法调用和
- 如何高效获取循环末次生成的 NumPy 数组最后一
- Win10如何卸载WindowsDefender_
- Win11怎么设置虚拟内存_Windows 11优
- Python函数接口稳定性_版本演进解析【指导】
- c++中如何进行二进制文件读写_c++ read与
- Win11怎么解压RAR文件 Win11自带解压功
- LINUX如何查看文件类型_Linux中file命
- Win11怎么卸载Photos应用_Win11卸载
- C++中的Pimpl idiom是什么,有什么好处
- mac怎么看硬盘大小_MAC查看磁盘存储空间与文件
- Win11怎么关闭透明效果_Windows11个性
- phpstudy本地环境mysql忘记密码_重置m
- c++ stringstream用法详解_c++字
- Python对象比较与排序_魔术方法解析【教程】
- 如何在Golang中实现并发消息队列消费者_Gol
- Win11开机Logo怎么换_Win11自定义启动
- Win11怎么关闭SmartScreen_禁用Wi
- Win11怎么开启自动HDR画质_Windows1
- Windows家庭版如何开启组策略(gpedit.
- c# 在高并发场景下,委托和接口调用的性能对比
- Python 中将 ISO 8601 时间戳转换为
- php中::能访问全局变量吗_全局作用域与类作用域
- Python爬虫项目实战教程_Scrapy抓取与存
- php怎么下载安装后设置错误日志_phpini l
- 如何使用Golang管理模块版本_Golanggo
- 如何在Golang中使用闭包_封装变量与函数作用域
- 如何使用Golang包导出规则_控制函数和变量可见
- Win10 BitLocker加密教程 Win10
- 如何在Golang中实现服务熔断与限流_Golan
- Win10任务栏天气和资讯怎么关闭 Win10禁用
- c# 如何用c#实现一个支持优先级的任务队列


QQ客服