Как просмотреть данные объекта DOMNodeList в php

когда я хочу протестировать php-массив, я использую следующий код

    print_r($myarray);

но знаю, что хочу видеть данные объекта мой объект

    $xpath = new DOMXPath($doc);
    $myobject = $xpath->query('//*[ancestor-or-self::a]');

когда я использую

    print_r($myobject);

Я получаю этот вывод

    DOMNodeList Object ( )

Я хочу выполнить итерацию значений этого объекта, чтобы проверить результат моего запроса?

Ответ 1

DOMNodeList - интересный объект, который не будет получать много информации из print_r или var_dump.

Существует множество способов просмотра данных объекта DOMNodeList. Вот пример:

$xpath = new DOMXpath($dom);
$dom_node_list = $xpath->query($your_xpath_query);
$temp_dom = new DOMDocument();
foreach($dom_node_list as $n) $temp_dom->appendChild($temp_dom->importNode($n,true));
print_r($temp_dom->saveHTML());

(Конечно, используйте saveXML вместо saveHTML, если вы имеете дело с XML.)

DOMNodeList можно повторить как массив. Если вы хотите вытащить данные из объекта DOMNodeList и поместить его в другую структуру данных, такую ​​как массив или объект stdClass, тогда вы просто перебираете "узлы" в DOMNodeList, преобразуя значения узлов и/или атрибуты (которые вы хотите иметь), прежде чем добавлять их в новую структуру данных.

Ответ 2

Можно перемещаться по узлам, используя простой foreach следующим образом:

foreach ($myobject as $node) {

  echo $node->nodeValue, PHP_EOL;

} // end foreach 

Надеюсь, что это может помочь другим, важными частями кода являются

foreach 

и элемент

$node->nodeValue

для более подробной информации об этом классе, пожалуйста, посетите:

http://php.net/manual/en/class.domnodelist.php

Ответ 4

var_dump($myobject); может быть тем, что вы ищете

Ответ 5

Ваш запрос xpath не соответствует чему-либо в вашем XML.

Из DomXPath:: страница справки руководства:

Возвращает список DOMNodeList, содержащий все узлы, соответствующие данному XPath выражение. Любое выражение, которое делает а не возвратные узлы возвращают пустой DOMNodeList.

Ответ 6

Как насчет рекурсивной функции?

Function XMLPrint_r($d_DomNode) {
    print $d_DomNode->$nodeName." ".$d_DomNode->$nodeValue."<br>";
    Foreach($d_DomNode->$childNodes as $d_ChildNode) {
        print " ";
        XMLPrint_r($d_ChildNode);
    }
}

Я не тестировал это, но вы поняли.

Ответ 7

По какой-то причине мне не удалось заставить методы saveHTML/saveXML работать. Поэтому я написал свою собственную рекурсивную рутину, которая работает для меня:

function pvIndent ( $ind ) {
    for ($i=0;$i<$ind;$i++)
        print ( "   " );
}

function pvPrint_r ( $val ) {
    echo '<pre>';
    print_r ( $val );
    echo '</pre>';
}

function pvDOMNodeListPrint_r_ ( $ind,$DOMNodeList ) {
    for ($item=0;$item<$DOMNodeList->length;$item++) {
        $DOMNode = $DOMNodeList->item($item);
        if ($DOMNode->nodeName != "#text") {
            pvIndent ( $ind );
            print $DOMNode->nodeName;
            if ($DOMNode->nodeValue)
                print " = " . trim($DOMNode->nodeValue);
            print "\n";
            if ($DOMNode->attributes)
                for ($attr=0;$attr<$DOMNode->attributes->length;$attr++) {
                    $DOMNodeAttr = $DOMNode->attributes->item($attr);
                    pvIndent ( $ind+1 );
                    print "@" . $DOMNodeAttr->nodeName . " = " . trim($DOMNodeAttr->nodeValue) . "\n";
                }
            if ($DOMNode->childNodes)
                pvDOMNodeListPrint_r_ ( $ind+1,$DOMNode->childNodes );
        }
    }
}

function pvDOMNodeListPrint_r ( $DOMNodeList ) {
    echo '<pre>';
    pvDOMNodeListPrint_r_ ( 0,$DOMNodeList );
    echo '</pre>';
}

Вызвать pvDOMNodeListPrint_r своим результатом запроса на объект XDOMPath.

Примечания:

pv - только префикс, который я использую, чтобы избежать загрязнения пространства имен - не стесняйтесь его редактировать.

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

Я явно пропустил DOMNode с именем "#text", поскольку они, похоже, повторяют текст, уже содержащийся в родительском node. Я не уверен, что это правильно для всех допустимых XDOMPath, загруженных HTML, но я еще не видел исключения - вы всегда можете исключить исключение, если не возражаете против обычной избыточности.

Ответ 8

Немного поздно в игре, но, возможно, это помогает кому-то...

Помните о выходе utf-8 при использовании самого объекта dom/xpath.

Если вы выведете nodeValue напрямую, вы получите поврежденные символы, например:

ìÂÂì ë¹ÂëÂ"Â"ì¤
ìì ë¹ë""ì¤ í°ì  íì¤

Вы должны загрузить свой объект dom со вторым параметром "utf-8", new \DomDocument('1.0', 'utf-8'), но при печати значения списка/элемента dom node вы получите сломанные символы:

echo $contentItem->item($index)->nodeValue

вам нужно обернуть его utf8_decode:

echo utf8_decode($contentItem->item($index)->nodeValue) //output: 者不終朝而會,愚者可浹旬而學

Ответ 9

После большой отладки я обнаружил, что все объекты DOM невидимы для var_dump() и print_r(), я предполагаю, что они являются объектами C, а не объектами PHP. Поэтому я попробовал saveXML(), который отлично работает в DOMDocument, но не реализован в DOMElement.

Решение прост (если вы это знаете):

$xml = $domElement->ownerDocument->saveXML($domElement);