PHP DOMDocument / XPath:获取HTML文本和包围的标签

时间:2011-10-24 11:45:55

标签: php html parsing tags domdocument

我正在寻找这个功能:

鉴于是这个html-Page:

<body>
 <h1>Hello,
  <b>world!</b>
 </h1>
</body>

我想获得一个只包含DISTINCT文本元素的数组 (没有重复)和围绕文本元素的标记数组:

上面“html”的结果将是一个如下所示的数组:

array => 
 "Hello," surrounded by => "h1" and "body"
 "world!" surrounded by => "b", "h1" and "body"

我想做到这一点:

$res=$xpath->query("//body//*/text()");

它给了我不同的文本内容,但省略了html标签。

当我这样做时:

$res=$xpath->query("//body//*");

我得到重复的文本,每个标记星座一个:例如:“世界!”会出现3次, 一次为“身体”,一次为“h1”,一次为“b”但我似乎无法 获取哪些文本是实际重复的信息。只检查重复文本是 不够,因为重复文本有时只是以前的文本或网站的子串 可能包含真正重复的文本,然后将其丢弃,这是错误的。

我该如何解决这个问题?

非常感谢!!

托马斯

2 个答案:

答案 0 :(得分:5)

您可以遍历parentNodesDOMText个节点:

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$textNodes = array();
foreach($xpath->query('/html/body//text()') as $i => $textNode) {
    $textNodes[$i] = array(
        'text' => $textNode->nodeValue,
        'parents' => array()
    );
    for (
        $currentNode = $textNode->parentNode;
        $currentNode->parentNode;
        $currentNode = $currentNode->parentNode
    ) {
        $textNodes[$i]['parents'][] = $currentNode->nodeName;
    }
}
print_r($textNodes);

demo

请注意,loadHTML会添加隐含元素,例如它将添加html和head元素,在使用XPath时您必须考虑这些元素。另请注意,用于格式化的任何空格都被视为DOMText,因此您可能会获得比预期更多的元素。如果您只想查询非空的DOMText节点,请使用

/html/body//text()[normalize-space(.) != ""]

demo

答案 1 :(得分:1)

在示例代码中,$res=$xpath->query("//body//*/text()")DOMNodeListDOMText个节点。对于每个DOMText,您可以通过parentNode属性访问包含元素。