【问题标题】:How to get nested divs , P Values with DomDocument - PHP [duplicate]如何使用 DomDocument 获取嵌套的 div、P 值 - PHP [重复]
【发布时间】:2021-07-01 23:52:16
【问题描述】:

我想从最里面的 DIV 访问 P 元素。也就是说,没有 DIV 子级的 DIV 的内容。 getElementsByTagName 可以做到这一点吗?

$html = '<html>
    <head>
        <title></title>
    </head>
    <body>
      <div class="">
            <div class="">
                   <p>  Content1  </p>
                   <p>  Content2  </p>
                
                        <div class="">
                               <p>  Content3  </p>
                               <p>  Content4  </p>
                        </div>
            </div>
    
          <p>  Content5  </p>
          <h2> Header </h2>
          <div class=""><p><strong> Content6 </strong></p> </div>
    
      </div>
    
        <div class=""> <p> Content7 </p></div>
        <div class="">
                       <p> Content8 </p>  
                       <p> Content9 </p> 
    
                       <div class="">
                              <p> Content10 </p>  
                       </div> 
              <span> blah.. </span>
        </div>
    </body></html>';

预期的输出如下:

Array
(
    [0] => Array
        (
            [0] =>   Content3  
            [1] =>   Content4  
        )

    [1] => Array
        (
            [0] =>  Content6 
        )

    [2] => Array
        (
            [0] =>  Content7 
        )

    [3] => Array
        (
            [0] =>  Content10 
        )
)

【问题讨论】:

  • 您之前尝试过使用 DOMDocument,不是吗?
  • 本题是上一题的延续,但略有不同
  • 是的,但您不接受此处的答案,根据您最初的问题,该答案是正确的。 stackoverflow.com/questions/66839401/how-to-get-divs-level这个问题,只需要稍微调整一下
  • 您对该问题的回答(作为 nice_dev)是绝对正确的。我对这个网站的系统不是很熟悉。您能否在这种情况下也提供帮助。
  • 是的,那是我的错字。我更正了问题

标签: php domdocument


【解决方案1】:

从我的回答 here 扩展,您将需要执行两个额外的步骤。

  • 检查当前父 div 是否没有任何其他 child divs
  • 根据 div 节点对 p 标记进行分组,您可以使用 spl_object_idp 节点与它们所属的相同父 div 节点进行匹配。

片段:

$ps = [];
$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'){
            if(isInnerMostChildDiv($curr_node)){
                if(!isset($ps[spl_object_id($curr_node)])) $ps[spl_object_id($curr_node)] = [];
                $ps[spl_object_id($curr_node)][] = $p->nodeValue;
            }            
            break;
        }
        $curr_node = $curr_node->parentNode;
        if($curr_node === null) break;
    }
}

function isInnerMostChildDiv($div_node){
    foreach($div_node->childNodes as $c_node){
        if(property_exists($c_node,'tagName') && $c_node->tagName == 'div' || !isInnerMostChildDiv($c_node)){
            return false;
        }
    }
    return true;
}

$ps = array_values($ps);

print_r($ps);

【讨论】:

  • 谢谢。你是最棒的,伙计。如何在输出中使用 saveHTML / XML?
  • @yaradan 欢迎。既然您想要的结果是数组格式,为什么需要将其保存为 HTML / XML?另外,我建议学习递归以更好地了解当前的解决方案。
  • 我的意思是,我的意思不是“内容”,而是“具有原始 HTML 结构的整个元素”。也就是说,应该打印“

    Content3

    ”而不是“Content1”
  • @yaradan 您可以查看上一个问题的答案来检索它。那个有ownerDocument
  • 我使用了以下代码,它工作正常。非常感谢您的帮助 $ps[spl_object_id($curr_node)][] = $p->ownerDocument->saveXML( $p );
猜你喜欢
  • 2020-07-22
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多