如何用PHP DomDocument获取body标签内的所有元素
问题:如何用PHP DOMDocument仅遍历body内的元素(不含自动生成的html/body标签)
我从数据库获取了一段不含html和body标签的HTML字符串,使用PHP DOMDocument的loadHTML方法解析时,会自动补全html和body标签。现在需要只遍历body标签内的子元素,不想使用XPath,仅用DOMDocument能否实现?
原始代码
$doc = new DOMDocument(); $doc->loadHTML($product['description']); // 来自数据库的HTML字符串 $els = $doc->getElementsByTagName('*'); foreach ($els as $node) { o($node->nodeName.' '.$node->nodeValue); }
示例HTML字符串
<p>This is a paragraph</p> <ol> <li>This is a list</li> </ol>
尝试过的无效方法
// 方法1:错误的选择器写法,getElementsByTagName不支持复合选择器 $els = $doc->getElementsByTagName('body *'); // 方法2:直接在DOMNodeList上调用方法,DOMNodeList无此方法 $body = $doc->getElementsByTagName('body'); $els = $body->getElementsByTagName('*');
解决方案(纯DOMDocument实现)
方法1:获取body节点后再查询所有元素
getElementsByTagName('body')返回的是DOMNodeList对象,必须先通过item(0)拿到唯一的body元素节点,再在该节点上调用getElementsByTagName('*'),即可获取body内的所有元素:
$doc = new DOMDocument(); $doc->loadHTML($product['description']); // 获取body元素节点 $bodyNode = $doc->getElementsByTagName('body')->item(0); // 查询body内的所有元素 $els = $bodyNode->getElementsByTagName('*'); foreach ($els as $node) { echo $node->nodeName . ' ' . $node->nodeValue . PHP_EOL; }
方法2:遍历body的子节点并过滤元素
如果需要更精准地控制(比如跳过空白文本节点),可以直接遍历body的childNodes,只处理元素类型的节点:
$doc = new DOMDocument(); $doc->loadHTML($product['description']); $bodyNode = $doc->getElementsByTagName('body')->item(0); foreach ($bodyNode->childNodes as $node) { // 仅处理元素节点(跳过文本、注释等非元素节点) if ($node->nodeType === XML_ELEMENT_NODE) { echo $node->nodeName . ' ' . $node->nodeValue . PHP_EOL; } }
内容的提问来源于stack exchange,提问作者Whip
相关产品推荐
相关产品推荐

