php DOMDocument: элемент заканчивается в другом - PullRequest
0 голосов
/ 23 июня 2019

У меня есть некоторый HTML, который содержит (среди прочего) p -тэги и figure -таги, которые содержат один img -таг.
Для простоты я определю пример того, чтоможно найти в HTML здесь в переменной PHP:

$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 ]

1 голос
/ 23 июня 2019

A 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>';
1 голос
/ 23 июня 2019

Перестановка выполняется с помощью опции LIBXML_HTML_NOIMPLIED, которую вы используете. Похоже, он недостаточно стабилен для вашего случая.

Посмотрите на этот ответ: loadHTML LIBXML_HTML_NOIMPLIED для фрагмента html создает неправильные теги А также Как сохранить HTML DOMDocument без HTML-оболочки?

Примечание : PHP 5.4 и Libxml 2.6 loadHTML теперь имеют параметр $ option, который инструктирует Libxml о том, как он должен анализировать содержимое.

...