PHP domDocument работает неправильно, когда обертка узла на рисунке?

Я пытаюсь добавить 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, она выдает правильный вывод:

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

Но когда это цифра, вывод очень странный — ссылка дублируется и вставляется в figcaption:

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

Это потому что DOMDocument не понимает figure вещь?

0

Решение

Я не смог воспроизвести вашу проблему. Мое предположение было бы неуместным элементом где-то в вашем исходном HTML. Но ваш код может быть немного упрощен.

Нет необходимости помещать ваши узлы изображения в массив, вы можете работать непосредственно с результатами DomDocument::getElementsByTagName(),

Как уже упоминалось в комментариях, вы можете настроить DomDocument::loadHTML() не добавлять doctype и подразумеваемые элементы, а не удалять их позже с помощью хитрых манипуляций со строками.

Просто DomDocument::createElement() может использоваться для элемента, который вы хотите добавить, вместо создания нового объекта.

В заключение, оператор контроля ошибок @ как правило, следует избегать. Вместо, libxml_use_internal_errors() может использоваться для установки поведения ошибки. Это позволяет вам просматривать сообщения об ошибках с 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>
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector