Search code examples
phpsimple-html-dom

Simple_html_dom: how to remove all elements with an attribute value, except the first one?


A few elements in my HTML page have the same value for the class attribute. I want to remove all of them (elements) except the first one.

I wrote the following SSCCE. So the question is

There are two loops being executed, the first one changes the attribute value for the first element and breaks the loop, and the second one then removes the elements with that attribute value.

So is there a shorter, less costly (in terms of memory, speed etc.) or more straightforward way to do this? May be can be done in a single loop or something like that? I feel I am making it unnecessarily long.

<?php

require_once("E:\\simple_html_dom.php");

$haystack = '<div>
    <div class="removable" style="background-color:pink; width:100%; height:50px;">aa</div>
    <div style="background-color:brown; width:100%; height:50px;">ss</div>
    <div class="removable" style="background-color:grey; width:100%; height:50px;">dd</div>
    <div class="removable" style="background-color:green; width:100%; height:50px;">gg</div>
    <div style="background-color:blue; width:100%; height:50px;">hh</div>
    <div class="removable" style="background-color:purple; width:100%; height:50px;">jj</div>
</div>';

$html_haystack = str_get_html($haystack);

//echo $html_haystack; //check

foreach ($html_haystack->find('div[class=removable]') as $removable) {
    $removable->class='removable_first';
    //$removable->style='background-color:black; width=100%; height=50px;'; //check
    break;
}

foreach($html_haystack->find('div[class=removable]') as $removable) {
    $removable->outertext= '';
}

$haystack = $html_haystack->save();

echo $haystack;

Solution

  • Find function returns an array, so the first element has index 0. No need then to use the 1st loop !

    // Get all nodes
    $array = $html_haystack->find('div[class=removable]');
    
    // Edit the 1st => maybe you won't need this line if you're doing so only to skip the 1st node
    $array[0]->class='removable_first';
    
    // Remove the 1st from the array
    unset($array[0]);
    
    // Loop through the other nodes
    foreach($array as $removable) {
        $removable->outertext= '';
    }