Alom
Alom

Reputation: 17

Loop through child elements by class of elements by class using PHP DomDocument

I need help with getting values from child nodes by class. Consider the following html:

<div class="category-inner-cont" data-count="1">
                <fieldset class="p20 blk-bordered" data-count="1">  
                    <legend class="legend" style="">
                        <input type="text" class="category-name" placeholder="Category/Group Name..." name="" value="One">
                    </legend>
                    <div class="input-group">
                        <input type="text" class="category-value" value="one-a">
                    </div>
                    <div class="input-group">
                        <input type="text" class="category-value" value="one-b">
                    </div>
                    <div class="input-group">
                        <input type="text" class="category-value" value="one-c">
                    </div>
                </fieldset>
            </div>

    <div class="category-inner-cont" data-count="2">
                <fieldset class="p20 blk-bordered" data-count="2">  
                    <legend class="legend" style="">
                        <input type="text" class="category-name" placeholder="Category/Group Name..." name="" value="Two">
                    </legend>
                    <div class="input-group">
                        <input type="text" class="category-value" value="two-a">
                    </div>
                    <div class="input-group">
                        <input type="text" class="category-value" value="two-b">
                    </div>
                </fieldset>
            </div>

I am trying to create an array to group each 'category-name' with the corresponding 'category-values' in each set of element of '.category-inner-cont'. I have the following php:

$org_contents = $html;
        $category_array = [];
        $category_names = [];
        $cat_value = [];
        $dom = new DOMDocument();
        $dom->preserveWhiteSpace = false;
        $dom->loadHTML($org_contents, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
        $cPath = new DOMXPath($dom);
        $categories = $cPath->query('//input[@class="category-name"]');
        foreach ($categories as $key => $cat) {
          $cat_values = $cPath->query('//input[ @class="category-value" ]');
            foreach ($cat_values as $v => $val) {
                $cat_value[] = $val->getAttribute('value');
            }
            $category_array[$key]['name'] = $cat->getAttribute('value');
            $category_array[$key]['values'] = $cat_value;

        }

However, its not getting my the correct results. The above produces the following:

0: {name: "One", values: ["one-a", "one-b", "one-c", "two-a", "two-b"]}
    name: "One"
    values: ["one-a", "one-b", "one-c", "two-a", "two-b"]
1: {name: "Two",…}
    name: "Two"
   values: ["one-a", "one-b", "one-c", "two-a", "two-b", "one-a", "one-b", "one-c", "two-a", "two-b"]

It should be producing

Name: One
Values: [one-a, one-b, one-c]
Name: Two
Values: [two-a, two-b]

Upvotes: 0

Views: 468

Answers (1)

Nigel Ren
Nigel Ren

Reputation: 57121

There were a couple of problems, one which was that the second XPath finds all of the values, without any idea of using the context of the current category you are working with. Using // in an XPath expression tells XPath to use any node to search for the content (and this includes parent nodes).

So this code uses the second parameter of query() to tell it where to start from, also adding a few ../ as it needs to back up the structure a bit to get the values (they are not in the same node or parent node as the category name attribute).

The code also resets $cat_value for each loop so that it doesn't retain values from the previous list of values...

    foreach ($categories as $key => $cat) {
        $cat_values = $cPath->query('../..//input[ @class="category-value" ]', $cat);
        $cat_value = [];
        foreach ($cat_values as $v => $val) {
            $cat_value[] = $val->getAttribute('value');
        }
        $category_array[$key]['name'] = $cat->getAttribute('value');
        $category_array[$key]['values'] = $cat_value;
    }

Upvotes: 1

Related Questions