我有一个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',
)
有人可以指出订单丢失的原因吗?
答案 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 {
/* ... */