PHP domDocument работает неправильно, когда обертка узла на рисунке? - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь добавить 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 вещь?

1 Ответ

0 голосов
/ 17 декабря 2018

Мне не удалось воспроизвести вашу проблему.Мое предположение было бы неуместным элементом где-то в вашем исходном 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>
...