PHP DOM解析<hr />标记之间的文本

时间:2017-03-30 21:09:57

标签: php dom domdocument

我正在尝试解析一些HTML,以便使用DOM和PHP在两个<hr>标记之间获取文本,但是当我将hr传入getElementsByTagName时,我没有得到任何输出:

<?php 
    $dom = new DOMDocument();
    $dom->loadHTML("<hr>Text<hr>");
    $hr = $dom->getElementsByTagName("hr");
    for ($i=0; $i<$hr->length; $i++) {
        echo "[". $i . "]" . $hr->item($i)->nodeValue . "</br>";
    }
?>

当我运行此代码时,它不输出任何内容,但如果我将"hr"更改为"*",则输出:

[0]Text
[1]Text
[2]
[3]

(为什么有四行结果?)

我在运行PHP 7.1.3版的网络服务器上运行此代码。我无法使用file_get_htmlstr_get_html等函数,因为它会返回有关函数未定义调用的错误...

为什么hr标记不会产生结果?

2 个答案:

答案 0 :(得分:4)

您正在寻找的是两个<hr>元素之间的文本节点的内容?在这种情况下,我们去寻找带有XPath表达式的兄弟姐妹:

<?php
$dom = new DOMDocument();
$dom->loadHTML("Some text<hr>The text<hr>Other text");
$xp = new DomXPath($dom);
$result = $xp->query("//text()[(preceding-sibling::hr and following-sibling::hr)]");
foreach ($result as $i=>$node) {
    echo "[$i]$node->textContent<br/>\n";
}

答案 1 :(得分:3)

这种情况发生了,因为<hr>没有子节点(文本也是子节点)。 要获取<hr>节点之间的文本,您必须迭代同一级别上的所有节点并检查当前节点是否为文本节点(nodeType == 3),前一个兄弟节点必须是{{1节点和下一个兄弟节点也必须是HR节点。

HR

但是如果你想在<?php $dom = new DOMDocument(); $dom->loadHTML("<hr>Text<hr>"); foreach ($dom->childNodes as $childNode) { if (3 !== $childNode->nodeType) { continue; } if (!$childNode->previousSibling || ('HR' !== $childNode->previousSibling->nodeName)) { continue; } if (!$childNode->nextSibling || ('HR' !== $childNode->nextSibling->nodeName)) { continue; } echo "{$childNode->nodeValue}\n"; } 节点之间获得任何,那将会更加复杂。