Ответ 1
Перестановка выполняется с помощью параметра LIBXML_HTML_NOIMPLIED
, который вы используете. Похоже, он недостаточно стабилен для вашего дела.
Также вы можете не использовать его по причинам, связанным с портабельностью, например, у меня есть один PHP 5.4.36 с Libxml 2.7.8 под рукой, который не поддерживает LIBXML_HTML_NOIMPLIED
(Libxml >= 2.7.7), но позже LIBXML_HTML_NODEFDTD
(Libxml >= 2.7.8).
Я знаю этот способ борьбы с этим. Когда вы загружаете фрагмент, вы завертываете его в элемент <div>
:
$doc->loadHTML("<div>$str</div>");
Это помогает вести DOMDocument в нужной структуре.
Вы можете извлечь этот контейнер из самого документа:
$container = $doc->getElementsByTagName('div')->item(0);
$container = $container->parentNode->removeChild($container);
И затем удалите всех детей из документа:
while ($doc->firstChild) {
$doc->removeChild($doc->firstChild);
}
Теперь документ полностью пуст, и теперь вы можете снова добавить детей. К счастью, элемент контейнера <div>
, который мы удалили ранее, мы можем добавить из него:
while ($container->firstChild ) {
$doc->appendChild($container->firstChild);
}
Затем фрагмент можно получить с помощью известного метода saveHTML:
echo $doc->saveHTML();
Что дает в вашем сценарии:
<p>Lorem ipsum dolor sit amet.</p><p>Nunc vel vehicula ante.</p>
Эта методология немного отличается от существующего материала здесь, на сайте (см. ссылки ниже), поэтому пример сразу:
$str = '<p>Lorem ipsum dolor sit amet.</p><p>Nunc vel vehicula ante.</p>';
$doc = new DOMDocument();
$doc->loadHTML("<div>$str</div>");
$container = $doc->getElementsByTagName('div')->item(0);
$container = $container->parentNode->removeChild($container);
while ($doc->firstChild) {
$doc->removeChild($doc->firstChild);
}
while ($container->firstChild ) {
$doc->appendChild($container->firstChild);
}
echo $doc->saveHTML();
Я также рекомендую ссылочный вопрос о том, как сохранитьHTML DOMDocument без оболочки HTML? для дальнейшего чтения, так же как и о inner-html