如何获得 DiVs 等级?
How To get DiVs Level?
$html ='<html>
<head>
<title></title>
</head>
<body>
<div class="">
<div class="">
<p><strong><span style="color:#FF0000"> Content1 </span></strong></p>
<p style="text-align:center"> Content2 <img src="https://example.com/bla1.jpg"/></p>
</div>
<h2> Header </h2>
<div class=""><p><strong> Content3 </strong></p> </div>
</div>
<div class=""> Content4 </div>
<div class="">
<p> Content5 </p>
<p> Content6 </p>
<span> blah.. </span>
</div>
</body></html>';
我需要这样一个数组:
这意味着每个DIV(包括P)是否有一个child或parent DIV ?
你的尝试不错,但我更愿意获取所有 p
标签,然后如果 div
是当前 [=] 的父节点,则爬升 DOM 节点层次结构14=]节点。这样,您将只收集那些 p
以 div
作为父节点的节点,而不是其他节点。换句话说,它就像 CSS 选择器 div > p
.
$ps = array();
$doc = new DomDocument('1.0', 'UTF-8');
$doc->loadHTML(mb_convert_encoding($HTML, 'HTML-ENTITIES', 'UTF-8'));
foreach($doc->getElementsByTagName('p') as $p){
$curr_node = $p->parentNode;
while(property_exists($curr_node,'tagName')){
if($curr_node->tagName == 'div'){
$ps[] = $p;
break;
}
$curr_node = $curr_node->parentNode;
if($curr_node === null) break;
}
}
print_r($ps);
更新#1:
要获得每个 div
的 p
,您可以递归遍历每个 div
的所有子节点并收集所有 p
并将其添加到结果中,如下所示:
function getPs($node,&$result){
foreach ($node->childNodes as $c_node) {
if(property_exists($c_node, 'tagName') && $c_node->tagName == 'p'){
$result[] = $c_node;
}
getPs($c_node,$result);
}
}
$ps = [];
foreach($doc->getElementsByTagName('div') as $div){
$child_ps = [];
getPs($div,$child_ps);
if(count($child_ps) > 0) $ps[] = $child_ps;
}
echo "<pre>";
print_r($ps);
更新#2:
要获取 p
节点的 HTML 字符串表示,更改
$result[] = $c_node;
到
$result[] = $c_node->ownerDocument->saveXML( $c_node );
除非您致力于仅将 getElementsByTagName
与 parent/child 选择器结合使用,否则您可能会发现一个简单的 XPath
查询是查找 p
最简单的方法位于 div
个元素内的元素。
$html ='<html>
<head>
<title></title>
</head>
<body>
<div class="">
<div class="">
<p><strong><span style="color:#FF0000"> Content1 </span></strong></p>
<p style="text-align:center"> Content2 <img src="https://example.com/bla1.jpg"/></p>
</div>
<h2> Header </h2>
<div class=""><p><strong> Content3 </strong></p> </div>
</div>
<div class=""> Content4 </div>
<div class="">
<p> Content5 </p>
<p> Content6 </p>
<span> blah.. </span>
</div>
</body></html>';
$tmp=array();
$dom=new DOMDocument;
$dom->loadHTML( $html );
$xp=new DOMXPath( $dom );
$col=$xp->query('//div/p');
if( $col && $col->length > 0 ){
foreach( $col as $node )$tmp[]=$node->textContent;
}
printf('<textarea cols=100 rows=10>%s</textarea>',print_r( $tmp, true ) );
产生:
更新:
与其存储 nodeValue / textContent,不如存储节点中包含的完整 HTML,因此为此,您 clone
节点(及其内容)并将其保存到输出数组。
$tmp=array();
$dom=new DOMDocument;
$dom->loadHTML( $html );
$xp=new DOMXPath( $dom );
$col=$xp->query('//div/p');
if( $col && $col->length > 0 ){
foreach( $col as $node ){
$clone=$node->cloneNode( true ); //clone node with ALL children
$tmp[]=$dom->saveHTML( $clone ); // save the HTML within
}
}
printf('<textarea cols=100 rows=10>%s</textarea>',print_r( $tmp, true ) );
$html ='<html>
<head>
<title></title>
</head>
<body>
<div class="">
<div class="">
<p><strong><span style="color:#FF0000"> Content1 </span></strong></p>
<p style="text-align:center"> Content2 <img src="https://example.com/bla1.jpg"/></p>
</div>
<h2> Header </h2>
<div class=""><p><strong> Content3 </strong></p> </div>
</div>
<div class=""> Content4 </div>
<div class="">
<p> Content5 </p>
<p> Content6 </p>
<span> blah.. </span>
</div>
</body></html>';
我需要这样一个数组:
这意味着每个DIV(包括P)是否有一个child或parent DIV ?
你的尝试不错,但我更愿意获取所有 p
标签,然后如果 div
是当前 [=] 的父节点,则爬升 DOM 节点层次结构14=]节点。这样,您将只收集那些 p
以 div
作为父节点的节点,而不是其他节点。换句话说,它就像 CSS 选择器 div > p
.
$ps = array();
$doc = new DomDocument('1.0', 'UTF-8');
$doc->loadHTML(mb_convert_encoding($HTML, 'HTML-ENTITIES', 'UTF-8'));
foreach($doc->getElementsByTagName('p') as $p){
$curr_node = $p->parentNode;
while(property_exists($curr_node,'tagName')){
if($curr_node->tagName == 'div'){
$ps[] = $p;
break;
}
$curr_node = $curr_node->parentNode;
if($curr_node === null) break;
}
}
print_r($ps);
更新#1:
要获得每个 div
的 p
,您可以递归遍历每个 div
的所有子节点并收集所有 p
并将其添加到结果中,如下所示:
function getPs($node,&$result){
foreach ($node->childNodes as $c_node) {
if(property_exists($c_node, 'tagName') && $c_node->tagName == 'p'){
$result[] = $c_node;
}
getPs($c_node,$result);
}
}
$ps = [];
foreach($doc->getElementsByTagName('div') as $div){
$child_ps = [];
getPs($div,$child_ps);
if(count($child_ps) > 0) $ps[] = $child_ps;
}
echo "<pre>";
print_r($ps);
更新#2:
要获取 p
节点的 HTML 字符串表示,更改
$result[] = $c_node;
到
$result[] = $c_node->ownerDocument->saveXML( $c_node );
除非您致力于仅将 getElementsByTagName
与 parent/child 选择器结合使用,否则您可能会发现一个简单的 XPath
查询是查找 p
最简单的方法位于 div
个元素内的元素。
$html ='<html>
<head>
<title></title>
</head>
<body>
<div class="">
<div class="">
<p><strong><span style="color:#FF0000"> Content1 </span></strong></p>
<p style="text-align:center"> Content2 <img src="https://example.com/bla1.jpg"/></p>
</div>
<h2> Header </h2>
<div class=""><p><strong> Content3 </strong></p> </div>
</div>
<div class=""> Content4 </div>
<div class="">
<p> Content5 </p>
<p> Content6 </p>
<span> blah.. </span>
</div>
</body></html>';
$tmp=array();
$dom=new DOMDocument;
$dom->loadHTML( $html );
$xp=new DOMXPath( $dom );
$col=$xp->query('//div/p');
if( $col && $col->length > 0 ){
foreach( $col as $node )$tmp[]=$node->textContent;
}
printf('<textarea cols=100 rows=10>%s</textarea>',print_r( $tmp, true ) );
产生:
更新:
与其存储 nodeValue / textContent,不如存储节点中包含的完整 HTML,因此为此,您 clone
节点(及其内容)并将其保存到输出数组。
$tmp=array();
$dom=new DOMDocument;
$dom->loadHTML( $html );
$xp=new DOMXPath( $dom );
$col=$xp->query('//div/p');
if( $col && $col->length > 0 ){
foreach( $col as $node ){
$clone=$node->cloneNode( true ); //clone node with ALL children
$tmp[]=$dom->saveHTML( $clone ); // save the HTML within
}
}
printf('<textarea cols=100 rows=10>%s</textarea>',print_r( $tmp, true ) );