PHP DOMDocument:元素在另一个元素中结束

时间:2019-06-23 14:36:45

标签: php domdocument

我有一些HTML,其中包含p标签和figure标签,其中包含一个img标签。
为了简单起见,我将在此处的PHP变量中定义一个示例,该示例可在HTML中找到:

$content = '<figure class="image image-style-align-left">
<img src="https://placekitten.com/g/200/300"></figure>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>';

我使用DOMDocument来获取$content,在本示例中,我将更改src元素中所有img元素的figure属性:

$dom = new DOMDocument();
libxml_use_internal_errors(true);

// this needs to be encoded otherwise special characters get messed up.
$domPart = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
$dom->loadHTML($domPart, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$domFigures = $dom->getElementsByTagName('figure');

foreach ($domFigures as $domFigure) {

    $img = $domFigure->getElementsByTagName('img')[0];
    if ($img) {
        $img->setAttribute('src', "https://placekitten.com/g/400/500");
    }

}

$result = $dom->saveHTML();

结果是:

<figure class="image image-style-align-left">
<img src="https://placekitten.com/g/400/500">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</figure>

我的p元素已以某种方式移入我的figure元素。 为什么会发生这种情况,我该怎么办?

Live DEMO

2 个答案:

答案 0 :(得分:1)

重新排列是通过您使用的LIBXML_HTML_NOIMPLIED选项完成的。看来您的情况不够稳定。

看看这个答案:Background TaskloadHTML LIBXML_HTML_NOIMPLIED on an html fragment generates incorrect tags

注意:PHP 5.4和Libxml 2.6 loadHTML现在具有一个$ option参数,该参数指示Libxml如何解析内容。

答案 1 :(得分:1)

DomDocument必须具有一个根元素,因此它将在第一个顶级元素内移动所有后续的同级元素。

通过使用容器标签预订内容,可以最轻松地解决这个问题。

$content = '<div><figure class="image image-style-align-left">
<img src="https://placekitten.com/g/200/300"></figure>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p></div>';