使用 PHP DomDocument 按 class 遍历 class 个元素的子元素

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

我需要 class 帮助从子节点获取值。 考虑以下 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>

我正在尝试创建一个数组,以在“.category-inner-cont”的每组元素中将每个 'category-name' 与对应的 'category-values' 分组。 我有以下 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;

        }

但是,它没有得到我正确的结果。以上产生以下内容:

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"]

应该在制作中

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

有几个问题,其中一个是第二个 XPath 找到了所有值,却没有使用您正在处理的当前类别的上下文。在 XPath 表达式中使用 // 告诉 XPath 使用任何节点来搜索内容(这包括父节点)。

所以这段代码使用 query() 的第二个参数来告诉它从哪里开始,还添加了一些 ../ 因为它需要稍微备份结构以获取值(它们与类别名称属性不在同一节点或父节点中。

该代码还为每个循环重置 $cat_value,这样它就不会保留先前值列表中的值...

    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;
    }