DOMDocument的ChildNodes丢失了订单

时间:2014-01-08 04:53:01

标签: php domdocument

我有一个html字符串。我想遍历它并提取一些信息。我的代码如下:

$str = '<p>aaa</p><img src="http://stackoverflow.com/questions/ask"/><p>sss</p><img src="http://stackoverflow.com/"/>';

function parseContent($str) {
    $contents = array();

    $dom = new DOMDocument('1.0', 'UTF-8');
    if (!$dom->loadHTML($str)) {
        return $contents;
    }

    $stack = array($dom);
    while (count($stack) > 0) {
        $node = array_shift($stack);
        foreach ($node->childNodes as $node) {
            if ($node->hasChildNodes()) {
                $stack[] = $node;
            } else {
                switch ($node->nodeType) {
                    case XML_ELEMENT_NODE:
                        if ('img' == $node->tagName) {
                            $contents[] = $node->attributes->getNamedItem('src')->nodeValue;
                        }
                        break;
                    case XML_TEXT_NODE:
                        $contents[] = $node->textContent;
                        break;
                }
            }
        }
    }

    return $contents;
}

问题是:当我转储此函数的返回值时,它是这样的:

array(
    'http://stackoverflow.com/questions/ask',
    'http://stackoverflow.com/',
    'aaa',
    'sss',
)

有人可以指出订单丢失的原因吗?

1 个答案:

答案 0 :(得分:0)

延伸评论:

这是因为每个<p>也有子节点(文本节点),因此它们会进入第一个if ($node->hasChildNodes())语句并再次堆叠。

为避免这种情况,一种方法是再添加一个条件:

/* ... */
if ($node->hasChildNodes()) {
    if ($node->childNodes->length==1 && $node->childNodes->item(0)->nodeType==XML_TEXT_NODE) {
        $contents[] = $node->childNodes->item(0)->textContent;
    } else {
        $stack[] = $node;
    }
} else {
/* ... */