PHP 图中的节点包装器时,domDocument 工作不正确?

PHP domDocument works incorrectly when the node wrapper in figure?

我正在尝试向所有包含图像的 link 添加一些 HTML。

基本 HTML 加载到 dom 看起来像

<div class='content'>
    <a href="..."><img src=""></a>

    <figure>
       <a href="..."><img src=""></a>
       <figcaption>Caption</figcaption>
    </figure>
</div>

代码:

$content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
$dom = new DOMDocument();
@$dom->loadHTML($content);

// Convert Images
$images = [];

foreach ($dom->getElementsByTagName('img') as $node) {
    $images[] = $node;
}

foreach ($images as $node) {    
     $field_html = $dom->createDocumentFragment(); // create fragment
     $field_html->appendXML('<span>11</span>'); // create fragment
     $node->parentNode->appendChild($field_html);  

}

$newHtml = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
return $newHtml; 

所以当它是带有 img 的常规 link 时,它会产生正确的输出:

<a href="..."><img src=""><span>11</span></a>

但是当它是一个数字时,输出很奇怪——link被复制并插入到figcaption中:

<figure>
    <a href="..."><img src=""></a>
    <figcaption>Caption <a href="..."><span>11</span>
    </figcaption>
</figure>

是因为 DOMDocument 不理解 figure 吗?

我无法重现您的问题。我的猜测是您源代码中某处放错了元素 HTML。但是您的代码可以简化很多。

无需将图像节点放入数组中,您可以直接使用 DomDocument::getElementsByTagName() 的结果。

如评论中所述,您可以设置 DomDocument::loadHTML() 不添加文档类型和隐含元素,而不是稍后通过可能棘手的字符串操作删除它们。

一个简单的 DomDocument::createElement() 可以用于您要追加的元素,而不是创建一个新对象。

最后,the error control operator @ should generally be avoided. Instead, libxml_use_internal_errors() can be used to set the error behaviour. This allows you to examine error messages with libxml_get_errors() 如果需要。

$content = <<< HTML
<div class="content">
    <a href="..."><img src=""></a>
    <figure>
       <a href="..."><img src=""></a>
       <figcaption>Caption</figcaption>
    </figure>
</div>
HTML;

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_use_internal_errors(false);

foreach ($dom->getElementsByTagName('img') as $node) {
     $node->parentNode->appendChild($dom->createElement("span", "11"));
}

$newHtml = $dom->saveHTML();
echo $newHtml;

输出:

<div class="content">
    <a href="..."><img src=""><span>11</span></a>
    <figure>
       <a href="..."><img src=""><span>11</span></a>
       <figcaption>Caption</figcaption>
    </figure>
</div>