我正在寻找这个功能:
鉴于是这个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”但我似乎无法 获取哪些文本是实际重复的信息。只检查重复文本是 不够,因为重复文本有时只是以前的文本或网站的子串 可能包含真正重复的文本,然后将其丢弃,这是错误的。
我该如何解决这个问题?
非常感谢!!
托马斯
答案 0 :(得分:5)
您可以遍历parentNodes个DOMText个节点:
$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);
请注意,loadHTML
会添加隐含元素,例如它将添加html和head元素,在使用XPath时您必须考虑这些元素。另请注意,用于格式化的任何空格都被视为DOMText,因此您可能会获得比预期更多的元素。如果您只想查询非空的DOMText节点,请使用
/html/body//text()[normalize-space(.) != ""]
答案 1 :(得分:1)
在示例代码中,$res=$xpath->query("//body//*/text()")
是DOMNodeList
个DOMText
个节点。对于每个DOMText
,您可以通过parentNode
属性访问包含元素。