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>
我正在尝试向所有包含图像的 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>