基于单级XML文件生成多维数组

时间:2012-01-10 21:45:53

标签: php arrays multidimensional-array

我(通过Web服务)接收包含类别,子类别,子类别等列表的平面XML文件,所有这些都在同一级别。 (即子类别不在其父类别下嵌套。)遗憾的是,这不能更改。我必须处理提供的数据。

我正在使用此XML并将其转换为对象,然后使用simplexml_load_stringarray_map将其转换为数组。这一切都按预期工作。我剩下的是一个主类别数组,看起来像这样。

Array
(
    [0] => Array
        (
            [CategoryID] => HARDWARE
            [Description] => Hardware Issue
        )
    [1] => Array
        (
            [CategoryID] => MAC_OSX
            [Description] => Mac OSX
            [ParentCategoryID] => OS
        )
    [2] => Array
        (
            [CategoryID] => OFFICE
            [Description] => Microsoft Office
            [ParentCategoryID] => SOFTWARE
        )
    [3] => Array
        (
            [CategoryID] => OS
            [Description] => Operating Systems
            [ParentCategoryID] => SOFTWARE
        )
    [4] => Array
        (
            [CategoryID] => WIN_7
            [Description] => Windows 7
            [ParentCategoryID] => OS
        )
    [5] => Array
        (
            [CategoryID] => SOFTWARE
            [Description] => Software Issue
        )
)

正如你所看到的,那里有一些子类别,都是ParentCategoryID的关键词。父类别省略了该字段。

CategoryID始终是唯一的,无论它处于什么级别。数组按Description的字母顺序排序。真正的数组超过250个类别,上面是一个缩写版本,例如清酒。

我需要接受主数组,遍历它并提出一个看起来像这样的新数组。

Array
(
    [0] => Array
        (
            [CategoryID] => SOFTWARE
            [Description] => Software Issue
            [SubCategories] => Array
                (
                    [0] => Array
                        (
                            [CategoryID] => OS
                            [Description] => Operating Systems
                            [SubCategories] => Array
                                (
                                    [0] => Array
                                        (
                                            [CategoryID] => WIN_7
                                            [Description] => Windows 7
                                        )
                                    [1] => Array
                                        (
                                            [CategoryID] => MAC_OSX
                                            [Description] => Mac OSX
                                        )
                                )
                        )
                    [1] => Array
                        (
                            [CategoryID] => OFFICE
                            [Description] => Microsoft Office
                        )
                )
        )
    [1] => Array
        (
            [CategoryID] => HARDWARE
            [Description] => Hardware Issue
        )
)

我必须记住的事情是可能存在无数多个子类别(因此没有一定数量的子级别我可以硬编码)。我一直试图弄乱array_searcharray_filter,但我没有运气好运。我显然不想为这个过程循环数百次。

对于多维阵列有更多经验的人是否有一些想法,方向或可以帮助我达到预期结果的例子?

2 个答案:

答案 0 :(得分:1)

好的,我想出了一个算法(我认为)。关键是要建立一个链表,并在列表中稍后使用占位符作为父类别。

创建一个类别obect,其中包括所有相关数据,指向其父级的链接以及指向其子级的链接数组。这些都将进入1d数组

接下来循环输入和:     如果有父类别,请检查我们是否已有对象。如果没有,请为父级创建占位符。     如果我们还没有对象,请为该类别创建一个对象。     在两个对象中设置父/子关系。

最后,再次循环遍历数组,并将没有父项的任何对象添加到新数组中。

这个新数组应该是所有父类别的列表,并指定您定义的关系,您应该能够像树一样浏览它。如果需要,您还可以执行另一次传递并构建本机2d数组。

答案 1 :(得分:0)

我终于明白了!现在看起来很简单,我几乎不好意思说要花很长时间才弄明白。这是我完成目标的最终代码。

if($cats['HasError'] == "false") {
    $cats = $cats['Support_SubjectsList']['Support_Subjects'];

    //Generate a hierarchy array of categories
    $count = count($cats);
    $i=0;
    while($count > 0) {
        foreach($cats as $k => $v) {
            if($i==0) {
                //Parents   
                if(is_array($v['ParentCategoryID'])) {
                    $categories[$i][$v['CategoryID']] = array("Description" => $v['Description']);
                    unset($cats[$k]);
                }
            } else {
                //Children
                if(array_key_exists($v['ParentCategoryID'], $categories[($i-1)])) {
                    $categories[$i][$v['CategoryID']] = array("Description" => $v['Description'], "ParentCategoryID" => $v['ParentCategoryID']);
                    unset($cats[$k]);
                }
            }
        }
        $count = count($cats);
        $i++;
    }

    //Traverse the hierarchy array backwards to make a nested category array
    $count = count($categories)-1;
    for($i=$count;$i>0;$i--) {
        foreach($categories[$i] as $k => $v) {
            $categories[($i-1)][$v['ParentCategoryID']]['SubCategories'][$k] = array("Description" => $v['Description']);
            if(is_array($v['SubCategories'])) {
                $categories[($i-1)][$v['ParentCategoryID']]['SubCategories'][$k]['SubCategories'] = $v['SubCategories'];
            }
        }
        unset($categories[$i]);
    }
    $categories = $categories[0];
}