PHP使用DOMXPath查询img标签时如何忽略script标签内的内容
问题根因
- 你大概率是用了
DOMDocument::loadXML()方法来加载HTML内容:XML解析器没有HTML中script标签的特殊处理逻辑,会把script内部的<img>当成正常的DOM标签解析。如果解析过程中出现语法错误(XML要求script内的<必须实体转义)且你屏蔽了错误提示,很容易出现DOM结构错乱,script标签被提前关闭,导致原本在script内的img节点变成和script同级的节点,not(ancestor::script)的过滤规则自然无法生效。 - 少数情况是使用
loadHTML()时没有屏蔽libxml错误,遇到不规范HTML时解析异常,导致DOM结构和预期不符。
解决方案
你的XPath逻辑本身没有问题,替换为符合HTML解析规则的加载方式即可:
$dom = new DOMDocument(); // 屏蔽HTML不规范产生的解析警告 libxml_use_internal_errors(true); // 加载HTML内容,两个参数分别是禁止自动补全html/body根标签、禁止插入默认DTD $dom->loadHTML('你的HTML源码字符串', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); libxml_clear_errors(); $xpath = new DOMXpath($dom); $imgs = $xpath->query('//img[not(ancestor::script)]');
如果你的场景必须使用loadXML()加载XHTML内容,需要确保所有script标签内部的特殊字符已经做了实体转义,或者用<![CDATA[ ]]>包裹script内容,同时XPath中的标签名和实际标签大小写保持一致。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

