Ошибка при разборе DOMDocument с PHP - PullRequest
0 голосов
/ 12 июня 2018

Мы обновляем наше ПО до PHP 7.2.3, и у меня есть следующий фрагмент кода, который отлично работал в предыдущих версиях:

$doc = new DOMDocument();
$doc->loadHTML("<html><body>".($_POST['reportForm_structure'])."</body></html>");

$root = $doc->documentElement->firstChild->firstChild->firstChild;
file_put_contents('D:\testoutput.txt', print_r($root ,true));

foreach($root->childNodes as $child) {
        if ($child->nodeName == "ul") {
            foreach($child->childNodes as $ulChild) {
                $this->loadNodes($ulChild, $this->report);
            }
        }           
    }

file_put_contents только для исследования ошибок.

Я получаю следующую ошибку: Invalid argument supplied for foreach().Сообщение относится к строке кода, где находится первый цикл foreach.Таким образом, структура данных не инициализирована правильно.Я вижу, что преобразование из HTML в DOMDocument больше не работает должным образом.Когда я проверяю вывод file_put_contents, я вижу, что $root является DOMText объектом вместо DOMElement объекта, но почему? Когда передается аргументиз loadHTML непосредственно в file_put_contents,

file_put_contents('D:\testoutput.txt', print_r("<html><body>".($_POST['reportForm_structure'])."</body></html>", true);

вывод выглядит как правильный HTML, поэтому я запутался, что больше не работаю.

<html><body><ul class="ltr">
<li class="open last" id="root" rel="root">
    <a href="#"><ins>&nbsp;</ins>HeaderText</a>
<ul><li class="open last" id="id1" rel="header"><a href="#"><ins>&nbsp;</ins>Test123</a>
<ul><li class="open leaf last" id="id2" rel="header"><a class="clicked" href="#"><ins>&nbsp;</ins>Test456</a></li></ul></li></ul></li>

Кто-нибудь знает, как решить эту проблему.Я что-то упустил в конфигурации здесь?

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Спасибо @Gordon и @DarsVaeda за то, что они указали мне правильное направление.DOMDocument интерпретирует возврат каретки и табуляцию как текстовые узлы.Я должен был удалить те, чтобы заставить это работать снова.Изменено

$doc->loadHTML("<html><body>".$_POST['reportForm_structure']."</body></html>");

на

$doc = new DOMDocument();       
$string = trim(preg_replace('/\t+/', '', $_POST['reportForm_structure']));
$string = preg_replace( "/\r|\n/", "", $string );       
$doc->loadHTML("<html><body>".$string."</body></html>");
0 голосов
/ 12 июня 2018

Я не смог воспроизвести узел DOMText с кодом, который вы показываете.Но я предполагаю, что вы сохраняете пробельные символы, а затем извлекаете пробельные узлы между элементом ul и элементом li.

                            v-------- whitespace node
<html><body><ul class="ltr">
<li class="open last" id="root" rel="root">

В любом случае, если вам нужен элемент с идентификатором «root», используйтеболее точный запрос, например, используйте

$root = $doc->getElementById("root");

Вы также можете установить $doc->preserveWhiteSpace = false, но лучше запрашивать узел по идентификатору, а не обходить три дочерних элемента и предполагать, что это тот узел.

...