XML 解析难题 [英] XML parsing conundrum

查看:26
本文介绍了XML 解析难题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我已经重新设计了这个问题,以显示我取得的进展,并且可能更容易回答.

更新 2:我向 XML 添加了另一个值.每个 zip 中都有扩展名.每个项目可以有多个由制表符分隔的项目.所以它的结构会是这样.平台 > 扩展(子组)> 名称 > 标题.如果该项目有多个扩展名,则它会出现在多个位置.

我有以下 XML 文件.

<平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 1</名称><Title>这是第一个文件组</Title><下载路径>/this/windows/1/1.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif 文档</Ext><名称>文件组 1</名称><Title>这是第一个文件组</Title><下载路径>/this/windows/1/2.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif</Ext><名称>文件组 1</名称><Title>这是在同一组中,但具有不同的标题</Title><下载路径>/this/windows/1/3.zip</DownloadPath></项目><物品><平台>Mac</平台><Ext>gif jpeg doc</Ext><名称>文件组 1</名称><Title>这有相同的组名,但不同的平台.因为它具有相同的标题和名称,所以文件被添加到下面的这个数组中.</Title><下载路径>/this/mac/1/1.zip</DownloadPath></项目><物品><平台>Mac</平台><Ext>jpeg doc</Ext><名称>文件组 1</名称><Title>这有相同的组名,但不同的平台.因为它具有相同的标题和名称,所以文件被添加到下面的这个数组中.</Title><下载路径>/this/mac/1/2.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 2</名称><Title>这是第二个文件组</Title><下载路径>/this/windows/2/1.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 2</名称><Title>这是第二个文件组</Title><下载路径>/this/windows/2/2.zip</DownloadPath></项目><物品><平台>Mac</平台><Ext>gif jpeg doc</Ext><名称>文件组 3</名称><Title>这确实是第二个 mac 文件组.</Title><下载路径>/this/windows/3/1.zip</DownloadPath></项目>

我希望能够通过它并对其进行排序,以便我可以将其插入到规范化的表模式中.这是我希望构建数组的格式.

[Windows] =>大批 ([0] =>大批(名称" =>"文件组 1",标题"=>"这是第一个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/1/1.zip"),[1] =>大批(下载路径" =>/this/windows/1/2.zip"))),[1] =>大批(名称" =>"文件组 1",标题"=>"这同名,不同名次,应该是分开的.",文件" =>大批([0] =>大批(下载路径" =>/this/windows/1/3.zip"))),[1] =>大批(名称" =>"文件组 2",标题"=>"这是第二个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/2/1.zip"),[1] =>大批(下载路径" =>/this/windows/2/2.zip")))),[Mac] =>大批([0] =>大批(名称" =>"文件组 1",标题"=>"它具有相同的组名但不同的平台.因为它具有相同的标题和名称,所以文件被添加到下面的这个数组中.",文件" =>大批([0] =>大批(下载路径" =>/this/mac/1/1.zip"),[1] =>大批(下载路径" =>/this/mac/1/2.zip"))),[1] =>大批(名称" =>"文件组 3",标题"=>"这真的是第二个 mac 文件组.",文件" =>大批([0] =>大批(下载路径" =>/this/mac/1/1.zip"),[1] =>大批(下载路径" =>/this/mac/1/2.zip"))),)

这是我目前使用的 php

 $scrape_xml = "files.xml";$xml = simplexml_load_file($scrape_xml);$groups = array();foreach ($xml->Item as $file){if (!isset($groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)])){$groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)] = array('平台' =>$文件->平台,'姓名' =>$文件->名称,'标题' =>$file->标题);}$groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)]['Files'][] = $file->DownloadPath;}回声计数=".$i;echo "

";print_r($groups);echo "</pre>";

它给了我这个结果

数组([视窗] =>大批([文件组 1] =>大批([这是第一个文件组] =>大批([平台] =>SimpleXMLElement 对象([0] =>视窗)[名称] =>SimpleXMLElement 对象([0] =>文件组 1)[标题] =>SimpleXMLElement 对象([0] =>这是第一个文件组)[文件] =>大批([0] =>SimpleXMLElement 对象([0] =>/this/windows/1/1.zip)[1] =>SimpleXMLElement 对象([0] =>/this/windows/1/2.zip)))[这是在同一组中,但具有不同的标题] =>大批([平台] =>SimpleXMLElement 对象([0] =>视窗)[名称] =>SimpleXMLElement 对象([0] =>文件组 1)[标题] =>SimpleXMLElement 对象([0] =>这是在同一组中,但具有不同的标题)[文件] =>大批([0] =>SimpleXMLElement 对象([0] =>/this/windows/1/3.zip))))[文件组 2] =>大批([这是第二个文件组] =>大批([平台] =>SimpleXMLElement 对象([0] =>视窗)[名称] =>SimpleXMLElement 对象([0] =>文件组 2)[标题] =>SimpleXMLElement 对象([0] =>这是第二个文件组)[文件] =>大批([0] =>SimpleXMLElement 对象([0] =>/this/windows/2/1.zip)[1] =>SimpleXMLElement 对象([0] =>/this/windows/2/2.zip)))))[Mac] =>大批([文件组 1] =>大批([这有相同的组名,但不同的平台.因为它具有相同的标题和名称,所以文件被添加到下面的这个数组中.] =>大批([平台] =>SimpleXMLElement 对象([0] =>苹果电脑)[名称] =>SimpleXMLElement 对象([0] =>文件组 1)[标题] =>SimpleXMLElement 对象([0] =>这具有相同的组名,但具有不同的平台.因为它具有相同的标题和名称,所以文件被添加到下面的这个数组中.)[文件] =>大批([0] =>SimpleXMLElement 对象([0] =>/this/mac/1/1.zip)[1] =>SimpleXMLElement 对象([0] =>/this/mac/1/2.zip))))[文件组 3] =>大批([这真的是第二个mac文件组.] =>大批([平台] =>SimpleXMLElement 对象([0] =>苹果电脑)[名称] =>SimpleXMLElement 对象([0] =>文件组 3)[标题] =>SimpleXMLElement 对象([0] =>这真的是第二个 mac 文件组.)[文件] =>大批([0] =>SimpleXMLElement 对象([0] =>/this/windows/3/1.zip))))))

更新 2:新的数组结构

[Windows] =>大批 ([gif] => 数组([0] =>大批(名称" =>"文件组 1",标题"=>"这是第一个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/1/1.zip"),[1] =>大批(下载路径" =>/this/windows/1/2.zip")))),[jpeg] =>大批([0] =>大批(名称" =>"文件组 1",标题"=>"这是第一个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/1/1.zip"),[1] =>大批(下载路径" =>/this/windows/1/2.zip"))),[1] =>大批(名称" =>"文件组 2",标题"=>"这是第二个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/2/1.zip"),[1] =>大批(下载路径" =>/this/windows/2/2.zip")))),[文档] =>大批([0] =>大批(名称" =>"文件组 1",标题"=>"这是第一个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/1/1.zip"),[1] =>大批(下载路径" =>/this/windows/1/2.zip"))),[1] =>大批(名称" =>"文件组 1",标题"=>"这同名,不同名次,应该是分开的.",文件" =>大批([0] =>大批(下载路径" =>/this/windows/1/3.zip"))),[2] =>大批(名称" =>"文件组 2",标题"=>"这是第二个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/windows/2/1.zip"),[1] =>大批(下载路径" =>/this/windows/2/2.zip"))))),[Mac] =>大批([gif] =>大批([0] =>大批(名称" =>"文件组 2",标题"=>"这是第二个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/mac/2/1.zip"),[1] =>大批(下载路径" =>/this/mac/2/2.zip"))),[1] =>大批(名称" =>"文件组 2",标题"=>"这是第二个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/mac/2/1.zip"),[1] =>大批(下载路径" =>/this/mac/2/2.zip"))),)[jepg] =>大批([0] =>大批(名称" =>"文件组 2",标题"=>"这是第二个文件组",文件" =>大批([0] =>大批(下载路径" =>/this/mac/2/1.zip"),[1] =>大批(下载路径" =>/this/mac/2/2.zip"))))[文档] =>大批([0] =>大批(名称" =>"文件组 1",标题"=>"这具有相同的组名但不同的平台.因为它具有相同的标题和名称,所以文件被添加到下面的这个数组中.",文件" =>大批([0] =>大批(下载路径" =>/this/mac/1/1.zip"),[1] =>大批(下载路径" =>/this/mac/1/2.zip"))),[1] =>大批(名称" =>"文件组 3",标题"=>"这真的是第二个 mac 文件组.",文件" =>大批([0] =>大批(下载路径" =>/this/mac/1/1.zip"),[1] =>大批(下载路径" =>/this/mac/1/2.zip")))))

更新 3:文件列表中有一些垃圾.

<平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 1</名称><Title>这是第一个文件组</Title><下载路径>/this/windows/1/1.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 1</名称><Title>这是第一个文件组</Title><下载路径>/this/windows/1/2.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 1</名称><Title>这是第一个文件组</Title><下载路径>/this/windows/2/1.zip</DownloadPath></项目><物品><平台>窗口</平台><Ext>gif jpeg doc</Ext><名称>文件组 1</名称><Title>这是第一个文件组</Title><下载路径>/this/windows/2/2.zip</DownloadPath></项目>

存在具有相同平台、扩展名、名称和标题的项目.上面的第 3 和第 4 项需要跳过,并将它们保存到一个我稍后会处理的数组中.

解决方案

您只是通过不同的排列方式将输入值映射到输出数组中,这就是您的结构:

数组([...项目/平台] =>大批 ([...项目/标题为 0-n] =>大批(名称" =>项目名称,标题"=>项目/标题,文件" =>大批([...] =>大批(下载路径" =>项目/下载路径),)),

映射可以通过迭代 XML 中的项目并将值存储到新数组中的适当位置来完成(我将其命名为 $build):

$build = array();foreach($items 作为 $item){$platform = (string) $item->Platform;$title = (string) $item->Title;isset($build[$platform][$title]) ?: $build[$platform][$title] = array('姓名' =>(string) $item->Name,'标题' =>$title);$build[$platform][$title]['Files'][] = array('DownloadPath' => (string) $item->DownloadPath);}$build = array_map('array_values', $build);

array_map 调用在最后完成以将 Item/Title 键转换为数字键.

就是这样,这里是 演示.

如果有帮助,请告诉我.

对于你更新的数据,对上面的稍作修改,前一个例子的关键原则仍然存在,它额外处理了每个项目每个附加扩展的额外重复,通过在内部添加另一个迭代:

$build = array();foreach($items 作为 $item){$platform = (string) $item->Platform;$title = (string) $item->Title;foreach(preg_split("~\s+~", $item->Ext) as $ext){isset($build[$platform][$ext][$title])?:$build[$platform][$ext][$title] = array('姓名' =>(string) $item->Name,'标题' =>$title);$build[$platform][$ext][$title]['文件'][]= array('DownloadPath' => (string) $item->DownloadPath);}}$build = array_map(function($v) {return array_map('array_values', $v);}, $build);

UPDATE: I've reworked the question, to show progress I've made, and maybe make it easier to answer.

UPDATE 2: I've added another value to the XML. Extension available in each zip. Each item can have multiple items separated by a tab. So it will be structured like this. Platform > Extension (Sub Group) > Name > Title. If the item has more than one extension then it will appear in multiple places.

I have the following XML file.

<Item>
    <Platform>Windows</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 1</Name>
    <Title>This is the first file group</Title>
    <DownloadPath>/this/windows/1/1.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif    doc</Ext>
    <Name>File Group 1</Name>
    <Title>This is the first file group</Title>
    <DownloadPath>/this/windows/1/2.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif</Ext>
    <Name>File Group 1</Name>
    <Title>This is in the same group but has a different title</Title>
    <DownloadPath>/this/windows/1/3.zip</DownloadPath>
</Item>
<Item>
    <Platform>Mac</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 1</Name>
    <Title>This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.</Title>
    <DownloadPath>/this/mac/1/1.zip</DownloadPath>
</Item>
<Item>
    <Platform>Mac</Platform>
    <Ext>jpeg   doc</Ext>
    <Name>File Group 1</Name>
    <Title>This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.</Title>
    <DownloadPath>/this/mac/1/2.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 2</Name>
    <Title>This is the second file group</Title>
    <DownloadPath>/this/windows/2/1.zip</DownloadPath>
</Item>
<Item>
    <Platform>Windows</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 2</Name>
    <Title>This is the second file group</Title>
    <DownloadPath>/this/windows/2/2.zip</DownloadPath>
</Item>
<Item>
    <Platform>Mac</Platform>
    <Ext>gif    jpeg    doc</Ext>
    <Name>File Group 3</Name>
    <Title>This is the second mac file group really.</Title>
    <DownloadPath>/this/windows/3/1.zip</DownloadPath>
</Item>

I want to be able to go through it and sort it so I can insert it into a normalized table schema. Here is the format I would like the array to built.

[Windows] => Array (
    [0] => array(
        "Name" => "File Group 1",
        "Title" => "This is the first file group",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/windows/1/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/windows/1/2.zip"
            )
        )
    ),
    [1] => array(
        "Name" => "File Group 1",
        "Title" => "This has the same name but has a different title, so it should be seperate.",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/windows/1/3.zip"
            )
        )
    ),
    [1] => array(
        "Name" => "File Group 2",
        "Title" => "This is the second file group",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/windows/2/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/windows/2/2.zip"
            )
        )
    )
),
[Mac] => Array(
    [0] => array(
        "Name" => "File Group 1",
        "Title" => "This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/mac/1/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/mac/1/2.zip"
            )
        )
    ),
    [1] => array(
        "Name" => "File Group 3",
        "Title" => "This is the second mac file group really.",
        "Files" => array(
            [0] => array(
                "DownloadPath" => "/this/mac/1/1.zip"
            ),
            [1] => array(
                "DownloadPath" => "/this/mac/1/2.zip"
            )
        )
    ),
)

Here is what I've got so far with my php

    $scrape_xml = "files.xml";
    $xml = simplexml_load_file($scrape_xml);

$groups = array();

foreach ($xml->Item as $file){

            if (!isset($groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)])){

                $groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)] = array(
                    'Platform' => $file->Platform,
                    'Name' => $file->Name,
                    'Title' => $file->Title
                );

            }

   $groups[stripslashes($file->Platform)][stripslashes($file->Name)][stripslashes($file->Title)]['Files'][] = $file->DownloadPath;

}

echo "count=" . $i;

echo "<pre>";
print_r($groups);
echo "</pre>";

it gives me this result

Array
(
    [Windows] => Array
        (
            [File Group 1] => Array
                (
                    [This is the first file group] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Windows
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 1
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is the first file group
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/1/1.zip
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/1/2.zip
                                        )

                                )

                        )

                    [This is in the same group but has a different title] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Windows
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 1
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is in the same group but has a different title
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/1/3.zip
                                        )

                                )

                        )

                )

            [File Group 2] => Array
                (
                    [This is the second file group] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Windows
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 2
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is the second file group
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/2/1.zip
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/2/2.zip
                                        )

                                )

                        )

                )

        )

    [Mac] => Array
        (
            [File Group 1] => Array
                (
                    [This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Mac
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 1
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/mac/1/1.zip
                                        )

                                    [1] => SimpleXMLElement Object
                                        (
                                            [0] => /this/mac/1/2.zip
                                        )

                                )

                        )

                )

            [File Group 3] => Array
                (
                    [This is the second mac file group really.] => Array
                        (
                            [Platform] => SimpleXMLElement Object
                                (
                                    [0] => Mac
                                )

                            [Name] => SimpleXMLElement Object
                                (
                                    [0] => File Group 3
                                )

                            [Title] => SimpleXMLElement Object
                                (
                                    [0] => This is the second mac file group really.
                                )

                            [Files] => Array
                                (
                                    [0] => SimpleXMLElement Object
                                        (
                                            [0] => /this/windows/3/1.zip
                                        )

                                )

                        )

                )

        )

)

UPDATE 2: New Array Structure

[Windows] => Array (
    [gif] =>Array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This is the first file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/1/2.zip"
                )
            )
        )
    ),
    [jpeg] => array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This is the first file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/1/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/2/2.zip"
                )
            )
        )
    ),
    [doc] => array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This is the first file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/1/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 1",
            "Title" => "This has the same name but has a different title, so it should be seperate.",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/1/3.zip"
                )
            )
        ),
        [2] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/windows/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/windows/2/2.zip"
                )
            )
        )
    )
),
[Mac] => Array(
    [gif] => array(
        [0] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/2/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/2/2.zip"
                )
            )
        ),

    )
    [jepg] => array(
        [0] => array(
            "Name" => "File Group 2",
            "Title" => "This is the second file group",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/2/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/2/2.zip"
                )
            )
        )
    )
    [doc] => array(
        [0] => array(
            "Name" => "File Group 1",
            "Title" => "This has the same group name but a different platform. Because it has the same title and name the files are added to this array below.",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/1/2.zip"
                )
            )
        ),
        [1] => array(
            "Name" => "File Group 3",
            "Title" => "This is the second mac file group really.",
            "Files" => array(
                [0] => array(
                    "DownloadPath" => "/this/mac/1/1.zip"
                ),
                [1] => array(
                    "DownloadPath" => "/this/mac/1/2.zip"
                )
            )
        )
    )
)

UPDATE 3: There is some garbage coming through for the file list.

<Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/1/1.zip</DownloadPath>
    </Item>
    <Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/1/2.zip</DownloadPath>
    </Item>
<Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/2/1.zip</DownloadPath>
    </Item>
    <Item>
        <Platform>Windows</Platform>
        <Ext>gif    jpeg    doc</Ext>
        <Name>File Group 1</Name>
        <Title>This is the first file group</Title>
        <DownloadPath>/this/windows/2/2.zip</DownloadPath>
    </Item>

There is a item with the same platform, extensions, name and title. Items 3 and 4 above need to be skipped over and save them to an array that I will handle later.

解决方案

You are merely mapping the input values into the output array by arranging them differently, this is your structure:

Array(
  [... Item/Platform] => Array (
    [... Item/Title as 0-n] => array(
        "Name" => Item/Name,
        "Title" => Item/Title,
        "Files" => array(
            [...] => array(
                "DownloadPath" => Item/DownloadPath
            ),
        )
    ),

The mapping can be done by iterating over the items within the XML and storing the values into the appropriate place in the new array (I named it $build):

$build = array();
foreach($items as $item)
{
    $platform = (string) $item->Platform;
    $title = (string) $item->Title;
    isset($build[$platform][$title]) ?: $build[$platform][$title] = array(
        'Name' => (string) $item->Name,
        'Title' => $title
    );
    $build[$platform][$title]['Files'][] = array('DownloadPath' => (string) $item->DownloadPath);
}
$build = array_map('array_values', $build);

The array_map call is done at the end to convert the Item/Title keys into numerical ones.

And that's it, here the Demo.

Let me know if that's helpful.

Edit: For your updated data, it's a slight modification of the above, the key principles of the previous example still exist, it's additionally taken care of the extra duplication per each additional extension per item, by adding another iteration inside:

$build = array();
foreach($items as $item)
{
    $platform = (string) $item->Platform;
    $title = (string) $item->Title;
    foreach(preg_split("~\s+~", $item->Ext) as $ext)
    {
        isset($build[$platform][$ext][$title])
            ?:$build[$platform][$ext][$title] = array(
                'Name' => (string) $item->Name,
                'Title' => $title
            );
        $build[$platform][$ext][$title]['Files'][]
            = array('DownloadPath' => (string) $item->DownloadPath);
    }
}
$build = array_map(function($v) {return array_map('array_values', $v);}, $build);

这篇关于XML 解析难题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆