Я задал этот вопрос вчера, и в то время это было именно то, что мне было нужно, но, работая с некоторыми живыми данными, я обнаружил, что это не совсем то, что я ожидал. Разбор HTML с HTML-кодом HTML DOMDocument
Он получает данные со страницы HTML, но затем также удаляет все теги HTML внутри захваченного блока текста, чего я не хочу. (Я мог бы не использовать некоторые теги, но не все, и это можно сделать позже)
Это общая проблема с DOM: вам нужно сделать немного больше работы, если вы хотите получить содержимое тега и содержимое всех его детей.
В принципе, вам нужно перебрать дочерние узлы того, который вы сопоставили с вашим запросом XPath, чтобы получить их содержимое.
Существует решение, предложенное в одном из примечаний пользователя на странице DOMElement
класса DOMElement
– см. Это примечание .
Интеграция этого решения в код, который у вас уже есть, должна дать вам что-то похожее на объявление строки HTML с субметками:
$html = <<<HTML <div class="main"> <div class="text"> <p> Capture this <strong>text</strong> <em>1</em> </p> <p> And some other <strong>text</strong> </p> </div> </div> HTML;
И, чтобы извлечь данные из этой строки HTML, вы можете использовать что-то вроде этого:
$dom = new DOMDocument(); $dom->loadHTML($html); $xpath = new DOMXPath($dom); $tags = $xpath->query('//div[@class="main"]/div[@class="text"]'); foreach ($tags as $tag) { $innerHTML = ''; // see http://fr.php.net/manual/en/class.domelement.php#86803 $children = $tag->childNodes; foreach ($children as $child) { $tmp_doc = new DOMDocument(); $tmp_doc->appendChild($tmp_doc->importNode($child,true)); $innerHTML .= $tmp_doc->saveHTML(); } var_dump(trim($innerHTML)); }
Единственное, что изменилось, это содержимое цикла foreach
: вместо того, чтобы просто использовать $tag->nodeValue
, вам нужно перебирать дочерние элементы.
Это дает мне следующий результат:
string '<p> Capture this <strong>text</strong> <em>1</em> </p> <p> And some other <strong>text</strong> </p>' (length=150)
Который является полным содержимым <div>
который был сопоставлен, и всех его дочерних элементов, включая теги.
Примечание: в заметках пользователей руководства часто есть интересные идеи и решения 😉
Ответ Паскаля МАРТИНА велик, но я нашел, что его можно упростить
$dom = new DOMDocument(); $dom->loadHTML($html); $xpath = new DOMXPath($dom); $tags = $xpath->query('//div[@class="main"]/div[@class="text"]'); foreach ($tags as $tag) { $innerHTML = ''; $children = $tag->childNodes; foreach ($children as $child) { $innerHTML .= $dom->saveHTML($child); } var_dump(trim($innerHTML)); }
Этот способ, похоже, дает тот же результат, но не требует DomDocument
новых объектов DomDocument
внутри цикла foreach
.
РЕДАКТИРОВАТЬ:
Поэтому, после дальнейших экспериментов, вы можете фактически уменьшить это:
$dom = new DOMDocument(); $dom->loadHTML($html); $xpath = new DOMXPath($dom); $tags = $xpath->query('//div[@class="main"]/div[@class="text"]'); foreach ($tags as $tag) { var_dump(trim($dom->saveHTML($tag))); }