使用PHP以递归方式查找xml子标记,同时跟踪父项

时间:2013-11-27 03:59:31

标签: php xml recursion

首先我要说明我刚刚学习这一切,所以我可能不会使用正确的术语。

这是我需要解析的XML的极简化版本:

 <MyXML>
    <Project>
        <ProjectName>MyProject</ProjectName>
        <ProjectType>Construction</ProjectType>
    </Project>
    <Folder>
        <folderid>0</folderid>
        <name>Root</name>
        <Depth></Depth>
        <Folder>
            <folderid>43943</folderid>
            <name>Construction Drawings</name>
            <ParentEntityID>0</ParentEntityID>
            <Folder>
                <folderid>43944</folderid>
                <name>Architectural</name>
                <ParentEntityID>43943</ParentEntityID>
                <Folder>
                    <folderid>43952</folderid>
                    <name>AutoCAD</name>
                    <ParentEntityID>43944</ParentEntityID>
                    <File>
                        <folderid>43952</folderid>
                        <filename>error.doc</filename>
                    </File>
                    <File>
                        <folderid>43952</folderid>
                        <filename>sb124a-map.jpg</filename>
                    </File>
                </Folder>
            </Folder>
        </Folder>
        <Folder>
            <folderid>43975</folderid>
            <name>Bid Management</name>
            <ParentEntityID>0</ParentEntityID>
            <File>
                <folderid>43975</folderid>
                <filename>ION Invoice 182 2013-04-09A.pdf</filename>
            </File>
            <Folder>
                <folderid>99999</folderid>
                <name>Temp</name>
                <ParentEntityID>43975</ParentEntityID>
                <File>
                    <folderid>99999</folderid>
                    <filename>ION Invoice 182 2013-04-09B.pdf</filename>
                </File>
            </Folder>
        </Folder>
    </Folder>
</MyXML>

正如您所看到的,文件夹的级别可变,文件分散在各个级别中。每个文件夹中还有一个引用它的父文件夹(ParentEntityID)的文件名称,并且每个文件也有一个对其父文件夹(folderid)的引用。不确定这是否有用。

我想要的是所有这些是csv中每个文件及其路径,项目名称和项目类型的列表,例如来自此XML:

MyProject,Construction,Root/Construction Drawings/Architectural/AutoCad, error.doc
MyProject,Construction,Root/Construction Drawings/Architectural/AutoCad, sb124a-map.jpg
MyProject,Construction,Root/Bid Management,ION Invoice 182 2013-04-09A.pdf
MyProject,Construction,Root/Bid Management/Temp,ION Invoice 182 2013-04-09B.pdf

我可以弄清楚如何捕获ProjectName和ProjectType,因为该结构始终是已知的并且是静态的。我觉得我需要对文件夹/文件部分的可变性进行某种递归,但我真的很挣扎。

在数千行的真实XML中,即使File元素也有我需要捕获数据的子元素,但我想如果我能理解如何处理这个简化的XML那么我应该能够弄清楚其余的部分。我希望。感谢。

1 个答案:

答案 0 :(得分:0)

你是对的,递归是获得这个结果的最佳方法。

<?php

function indepth($path, $current_folder)
{
    global $project_name, $project_type;
    $path[] = $current_folder->name;    
    foreach ($current_folder->File as $file) {
        echo $project_name . ',' . $project_type . ',' . implode('/', $path) . ', ' . $file->filename . "\n";
    }
    foreach ($current_folder->Folder as $folder) {
        indepth($path, $folder);
    }
}

$myxml = simplexml_load_file('test.xml');
$project_name = $myxml->Project->ProjectName;
$project_type = $myxml->Project->ProjectType;

foreach ($myxml->Folder as $folder) {
    indepth(array(), $folder);
}

使用global通常不是一个好习惯,但在这里它允许访问indepth()中的项目变量,而不将它们作为每个递归调用的参数传递。