How to extract Element contents of a parent element having most <p> Tag

Viewed 68

I have a html file with the below classes but I need to extract only the <p> tags having most in number than any other classes.

Like <div class="text"> as 18 <p> tags and <div class="another-text"> has 3 <p> tags and <div class="another-another-text"> has 2 <p> tags. I need to extract the <p> tags in <div class="text"> class.

<body>
    <div class="text">
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
      <p>...</p>
    </div>

  <div class="another-text">
    <p>...</p>
    <p>...</p>
    <p>...</p>
  </div>

  <div class="another-another-text">
    <p>...</p>
    <p>...</p>
  </div>
</body>
2 Answers

Due to xpath support limitations in php, you'll have to resort to something like:

$html= 
'[your html above]

';
$HTMLDoc = new DOMDocument();
$HTMLDoc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );   
$xpath = new DOMXPath($HTMLDoc);

#locate the 3 divs
$pees = $xpath->query('//div[.//p]');
$pchilds = [];

#get the number of p children in each div
foreach ($pees as $pee) {
    $childs = $pee->childElementCount;
    array_push($pchilds,$childs);}

#now find the div with the max number of p children
foreach ($pees as $pee) {
    $childs = $pee->childElementCount;
    if ($childs == max($pchilds))
       echo ($pee->nodeValue);
       #or do whatever
}

FYI, with xpath 2.0 support, this can be done with a one line xpath expression:

//div[count(.//p) = max(//div/count(.//p))]

If the divs are in the same parent it can be done by this XPath:

//div[count(p) &gt; count(preceding-sibling::div/p) and count(p) &gt; count(following-sibling::div/p)] 

If the divs are not in the same parent it can be done by this XPath:

//div[count(p) &gt; count(preceding::div/p) and count(p) &gt; count(following::div/p)]
Related