使用PHP DOMDocument删除li下p子节点无效果如何解决?
问题原因
你的代码存在3个核心错误导致功能不生效:
- 节点定位错误:
$li->parentNode指向的是li的上层元素(示例中的ol),而非li本身,你要删除的是li的子节点,不需要调用父节点的方法 - 方法传参错误:
removeChild要求传入DOM节点对象作为参数,不能直接传入标签名字符串'p',语法不符合规范 - 遍历逻辑缺陷:
getElementsByTagName返回的是动态DOM节点集合,遍历过程中修改DOM结构会导致节点索引错乱,出现漏处理的情况
修正后代码
$dom = new \DOMDocument(); // 屏蔽HTML非标准语法警告,非必需但可避免无关报错 libxml_use_internal_errors(true); $dom->loadHTML($contenido); libxml_clear_errors(); // 转为静态数组避免动态集合遍历异常 $liNodes = iterator_to_array($dom->getElementsByTagName('li')); foreach ($liNodes as $li) { $li->removeAttribute('class'); $li->removeAttribute('style'); // 取出当前li下所有p节点 $pNodes = iterator_to_array($li->getElementsByTagName('p')); foreach ($pNodes as $p) { $li->removeChild($p); } } // 输出处理后的HTML // echo $dom->saveHTML();
如果你需要保留p标签内的文本内容,仅移除p标签的包裹,可将内部删除p的逻辑替换为以下代码:
foreach ($pNodes as $p) { // 把p的所有子节点移到li下,插入到p的前面 while ($p->hasChildNodes()) { $li->insertBefore($p->firstChild, $p); } // 移除空的p标签 $li->removeChild($p); }
内容的提问来源于stack exchange,提问作者salvador
相关产品推荐
相关产品推荐

