Я пытаюсь разобрать конкретный html-документ, какой-то словарь, содержащий около 10000 слов и описание. Это прошло хорошо, пока я не заметил, что записи в определенном формате не получают синтаксический анализ.
Вот пример:
<?php $html = ' <p> <b> <span>zot; zotz </span> </b> <span>Nista; nula. Isto <b>zilch; zip.</b> </span> </p> '; $xml = simplexml_load_string($html); var_dump($xml); ?>
Результатом var_dump () является:
object(SimpleXMLElement)#1 (2) { ["b"]=> object(SimpleXMLElement)#2 (1) { ["span"]=> string(10) "zot; zotz " } ["span"]=> string(39) "Nista; nula. Isto " }
Как вы можете видеть – Simplexml сохранил текстовый узел внутри тега, но оставил дочерний узел и текст внутри.
Я также пробовал:
$doc = new DOMDocument(); $doc->loadHTML($html); $xml = simplexml_import_dom($doc);
с тем же результатом.
Поскольку мне казалось, что это обычная проблема при анализе html, я попытался разобраться с этим, но только место, которое признает эту проблему в этом блоге: https://hakre.wordpress.com/2013/07/09/simplexml-and- json-encode-in-php-part-i /, но не предлагает никакого решения.
Есть только слишком обобщенные сообщения и ответы о разборе HTML в SO.
Есть ли простой способ справиться с этим? Или я должен изменить свою стратегию?
Ваше замечание верно: SimpleXML предлагает только дочерний элемент-узел, а не дочерние текстовые узлы. Решение состоит в том, чтобы переключиться на DOMDocument, поскольку он может обращаться ко всем узлам, текстовым и дочерним элементам.
// first span element $span = dom_import_simplexml($xml->span); foreach ($span->childNodes as $child) { printf(" - %s : %s\n", get_class($child), $child->nodeValue ); }
В этом примере показано, что dom_import_simplexml
используется для более конкретного элемента элемента <span>
и обход выполняется над дочерними элементами соответствующего объекта DOMElement .
Выход:
- DOMText : Nista; nula. Isto - DOMElement : zilch; zip. - DOMText :
-- DOMText : Nista; nula. Isto - DOMElement : zilch; zip. - DOMText :
Первая запись – это первый текстовый узел в элементе <span>
. За ним следует элемент <b>
(который снова содержит некоторый текст), а затем из другого текстового узла, который состоит только из пробелов.
Функция dom_import_simplexml
особенно полезна, когда SimpleXMLElement слишком прост для более дифференцированного доступа к данным в XML-документе. Как и в случае с вами.
Пример полностью:
$html = <<<HTML <p> <b> <span>zot; zotz </span> </b> <span>Nista; nula. Isto <b>zilch; zip.</b> </span> </p> HTML; $xml = simplexml_load_string($html); // first span element $span = dom_import_simplexml($xml->span); foreach ($span->childNodes as $child) { printf(" - %s : %s\n", get_class($child), $child->nodeValue ); }
-$html = <<<HTML <p> <b> <span>zot; zotz </span> </b> <span>Nista; nula. Isto <b>zilch; zip.</b> </span> </p> HTML; $xml = simplexml_load_string($html); // first span element $span = dom_import_simplexml($xml->span); foreach ($span->childNodes as $child) { printf(" - %s : %s\n", get_class($child), $child->nodeValue ); }