如何在php中查看DOMNodeList对象的数据

时间:2009-09-02 03:54:17

标签: php dom xpath domdocument

当我想测试php数组时,我使用以下代码

    print_r($myarray);

但知道我想看到一个对象的数据 我的目标是

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

当我使用

    print_r($myobject);

我得到了那个输出

    DOMNodeList Object ( )

我想迭代这个对象的值来测试我的查询结果吗?

9 个答案:

答案 0 :(得分:21)

DOMNodeList是一个有趣的对象,您无法使用print_rvar_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());

(当然,如果要处理XML,请使用saveXML而不是saveHTML。)

DOMNodeList可以像数组一样迭代。如果要从DOMNodeList对象中提取数据并将其放入不同的数据结构(如数组或stdClass对象),则只需遍历DOMNodeList中的“节点”,转换节点的值和/或在将属性添加到新数据结构之前,您希望它们具有可用性。

答案 1 :(得分:4)

可以使用简单的foreach在节点中导航,如下所示:

foreach ($myobject as $node) {

  echo $node->nodeValue, PHP_EOL;

} // end foreach 

希望它可以帮助别人,重要的代码片段是

foreach 

和项目

$node->nodeValue

有关此课程的更多详情,请访问:

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

答案 2 :(得分:2)

有人写了一个很棒的getArray()函数: http://www.php.net/manual/en/class.domdocument.php#101014

答案 3 :(得分:1)

递归函数怎么样?

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);
    }
}

我没有测试过,但你明白了。

答案 4 :(得分:1)

出于某种原因,我无法使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>';
}

使用您对XDOMPath对象的查询结果调用pvDOMNodeListPrint_r。

注意:

pv只是我用来避免名称空间污染的前缀 - 随时可以编辑它。

使用预标记,因此在html正文中输出格式时,可以正确处理空格和换行符,这是我通常需要这样的调试语句的地方 - 您可以根据自己的喜好进行格式化。

我明确地跳过了名为&#34;#text&#34;的DOMNode&#34;因为这些似乎重复了父节点中已经包含的文本。我不确定所有有效的XDOM路由HTML加载是否正确,但我还没有看到异常 - 如果你不介意通常的冗余,你总是可以排除这种情况

答案 5 :(得分:1)

比赛有点晚,但也许有人帮助......

使用dom / xpath对象时,请注意utf-8输出。

如果您直接输出nodeValue,您将收到损坏的字符,例如:

ìÂÂì ë¹Â디ì¤
ìì ë¹ë””ì¤ í°ì  íì¤

你必须使用第二个参数“utf-8”,new \DomDocument('1.0', 'utf-8')加载你的dom对象,但是当你打印dom节点列表/元素值时,你会得到破碎的字符:

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

你必须用utf8_decode包装它:

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

答案 6 :(得分:0)

var_dump($myobject);可能就是你要找的东西

答案 7 :(得分:0)

您的xpath查询与XML中的任何内容都不匹配。

来自DomXPath::query manual page

  

返回包含all的DOMNodeList   与给定XPath匹配的节点   表达。做任何表达   不返回节点将返回空   的DOMNodeList。

答案 8 :(得分:-1)

经过大量调试后我发现所有DOM对象对var_dump()和print_r()都是不可见的,我的猜测是因为它们是C对象而不是PHP对象。所以我尝试了saveXML(),它在DOMDocument上工作正常,但没有在DOMElement上实现。

解决方案很简单(如果你知道的话):

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