Search code examples
phpsimple-html-dom

PHP : Simple DOM Parser how to iterate html code


<div class="reviews-summary__stats">
    <div class="reviews-summary">
        <p class="reviews-title">C</p>
        <ul class="rating">
            <li class="rating__item rating__rated"></li>
            <li class="rating__item rating__rated"></li>
            <li class="rating__item rating__rated"></li>
            <li class="rating__item "></li>
            <li class="rating__item "></li>
        </ul>
    </div>
    <div class="reviews-summary">
        <p class="reviews-title">C</p>
        <ul class="rating">
            <li class="rating__item rating__rated"></li>
            <li class="rating__item rating__rated"></li>
            <li class="rating__item rating__rated"></li>
            <li class="rating__item rating__rated"></li>
            <li class="rating__item "></li>
            <li class="rating__item "></li>
        </ul>
    </div>
    <div class="reviews-summary">
        <p class="reviews-title">C</p>
        <ul class="rating">
            <li class="rating__item rating__rated"></li>
            <li class="rating__item rating__rated"></li>
            <li class="rating__item "></li>
            <li class="rating__item "></li>
        </ul>
    </div>     
</div>

i want to iterate over each div.reviews-summary but i am not getting to next p.reviews-title and li.rating__item rating__rated tag, also count li.rating__item rating__rated for display li.rating__item rating__rated in integer.

<?php
    include("simple_html_dom.php");
    $obj = new simple_html_dom();

    foreach ($obj->find('div[class=reviews-summary]') as $factor)
    {
        $item = $factor->find('p[class=reviews-title]')->plaintext;

        if(trim($item) == 'A')
        { 
            $a = $factor->find('li[class=rating__item rating__rated]',0)->plaintext;
        }
        if(trim($item) == 'B')
        { 
            $b = $factor->find('li[class=rating__item rating__rated]',0)->plaintext;
        }
        if(trim($item) == 'C')
        { 
            $c = $factor->find('li[class=rating__item rating__rated]',0)->plaintext;
        }
        $final_array['overalldata'] = array
        (
            'a' => $a,   // no of A have <li class="rating__item rating__rated"></li> 
            'b' => $b,
            'c' => $c,
        );
    }
    print_r($final_array);
    die;
?>

i want display like this type of output, Array ( [overalldata] => Array ( [a] => 3
[b] => 4
[c] => 2
) )
and also count the li.rating__item rating__rated it, and display integer value of no of li.rating__item rating__rated are exist in list

Any body having any idea please help to sort it out. Thanks


Solution

  • I've made a couple of changes, but have included a couple of versions as they both format the data differently. I think the main problem was that when you use find(), this may return a list of items found and so when setting $a etc. you had used the second parameter to pick out the plaintext of the first item (using ,0), you didn't do this when looking for the $item value. So I've added the same to this call.

    $final_array=array();
    foreach ($obj->find('div[class=reviews-summary]') as $factor)
    {
        $item = $factor->find('p[class=reviews-title]',0)->plaintext;
        if(trim($item) == 'A')
        {
            $final_array['overalldata']['a'] = $factor->find('li[class=rating__item rating__rated]',0)->plaintext;
        }
        if(trim($item) == 'B')
        {
            $final_array['overalldata']['b'] = $factor->find('li[class=rating__item rating__rated]',0)->plaintext;
        }
        if(trim($item) == 'C')
        {
            $final_array['overalldata']['c'] = $factor->find('li[class="rating__item rating__rated"]',0)->plaintext;
        }
    }
    print_r($final_array);
    

    This gives (with your sample data)...

    Array
    (
        [overalldata] => Array
            (
                [c] => 
            )
    
    )
    

    Alternatively...

    $final_array=array();
    foreach ($obj->find('div[class=reviews-summary]') as $factor)
    {
        $a = null;
        $b = null;
        $c = null;
        $item = trim($factor->find('p[class=reviews-title]',0)->plaintext);
        $factor = $factor->find('li[class=rating__item rating__rated]');
        $count = count($factor);
        if($item == 'A')
        {
            $a = $factor[0]->plaintext;
        }
        if($item == 'B')
        {
            $b = $factor[0]->plaintext;
        }
        if($item == 'C')
        {
            $c = $factor[0]->plaintext;
        }
        $final_array['overalldata'] = array
        (
            'a' => $a,
            'b' => $b,
            'c' => $c,
            'count' =>$count
        );
    }
    print_r($final_array);
    

    With a slightly altered set of test data gives...

    Array
    (
        [overalldata] => Array
            (
                [a] => 
                [b] => 
                [c] => Some content
            )
    
    )
    

    Update:

    I've updated the second example, I've moved some of the common code into the main part. The $count is just the number of <li class="rating__item rating__rated"> items (I think this is what your asking for).