У меня есть HTML-документ с такой не очень хорошей разметкой, без ‘ul’:
<p>Lorem</p>
<p>Ipsum...</p>
<li class='item'>...</li>
<li class='item'>...</li>
<li class='item'>...</li>
<div>...</div>
Сейчас я пытаюсь «схватить» все li-элементы и обернуть их в ul-список, который я хотел бы разместить в одном месте, используя PHP и DOMXPath. Мне удается найти и «удалить» элементы li:
$elements = $xpath->query('//li[@class="item"]');
$wrapper = $document->createElement('ul');
foreach($elements as $child) {
$wrapper->appendChild($child);
}
Может быть, вы можете получить parentNode
из первых <li>
а затем использовать insertBefore
метод:
$html = <<<HTML
<p>Lorem</p>
<p>Ipsum...</p>
<li class='item'>...</li>
<li class='item'>...</li>
<li class='item'>...</li>
<div>...</div>
HTML;
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$elements = $xpath->query('//li[@class="item"]');
$wrapper = $doc->createElement('ul');
$elements->item(0)->parentNode->insertBefore(
$wrapper, $elements->item(0)
);
foreach($elements as $child) {
$wrapper->appendChild($child);
}
echo $doc->saveHTML();
Вот что тебе нужно. Возможно, вам придется настроить запрос XPath для вашего реального HTML.
$document = new DOMDocument;
// We don't want to bother with white spaces
$document->preserveWhiteSpace = false;
$html = <<<EOT
<p>Lorem</p>
<p>Ipsum...</p>
<li class='item'>...</li>
<li class='item'>...</li>
<li class='item'>last...</li>
<div>...</div>
EOT;
$document->LoadHtml($html);
$xpath = new DOMXPath($document);
$elements = $xpath->query('//li[@class="item"]');
// Saves a reference to the Node that is positioned right after our li's
$ref = $xpath->query('//li[@class="item"][last()]')->item(0)->nextSibling;
$wrapper = $document->createElement('ul');
foreach($elements as $child) {
$wrapper->appendChild($child);
}
$ref->parentNode->insertBefore($wrapper, $ref);
echo $document->saveHTML();
Бегущий пример: https://repl.it/B3UO/24