2012-02-18 78 views
0

我有一個小應用程序,執行以下操作:如何在輸出中包含子元素的每個子元素? PHP

  • 允許用戶在一個XML文件
  • 解析XML文件上傳到一個數組$ _SESSION
  • 顯示父列表工作元素名稱,用戶可以選擇查看
  • 解析陣列來顯示所選父元素的孩子

的問題是,每項目可以有可以生孩子的孩子......等等,這可以無限期地繼續下去。

如何在最終輸出中包含孩子的每個孩子?

的XML文件可以類似於這樣:

<thing> 
    <parents> 
    <parent> 
     <name>parent 1</name> 
     <categories> 
     <category> 
      <name>category 1</name> 
      <items> 
      <item> 
       <name>item 1 (gen 1)</name> 
       <items> 
       <item> 
        <name>sub-item 1 (gen 2)</name> 
        <items> 
        <item> 
         <name>sub-sub-item 1 (gen 3)</name> 
         ...this could continue forever.. 
        </item> 
        </items> 
       </item> 
       </items> 
      </item> 
      </items> 
     </category> 
     </categories> 
    </parent> 
    </parents> 
</thing> 

我在解析XML與PHP的SimpleXML的數組。每個文件都必須有父項,類別和第一代子項目。下面的代碼解析了這三個層次的結構,但除此之外,我迷了路。

$output .= '<ul>'; 
foreach($xml['parents'] as $parent){ 
    $output .= '<li>'.$parent['name'].'</li>'; 
    foreach($parent['categories']['category'] as $category){ 
    $output .= '<li>'.$category['name'].'</li>'; 
    foreach($category['items']['item'] as $item){ 
     $output .= '<li>'.$item['name'].'</li>'; 
     // here is where the $item can have children w/ children 
     // who can have children who can have children... etc... forever. 
     // (i.e. $item['items']['item'] as $generation2_items++...) 
     // 
     // I want to add them as another <li></li>... 
     // 
     // How can you account for unknown # of children? 
    } 
    } 
} 
$output .= '</ul>'; 
echo $output; 

碼$輸出類似於清單:

- parent 1 
-- category 1 
--- item 1 (gen 1) 
---- sub item 1 (gen 2) 
----- sub-sub item 1 (gen 3) 
------- etc. 
-------- etc. 

你怎麼能確定每個項目有多少子元素深雲,然後你怎麼能創造足夠的迴路通過相應的解析......或通過另一種方式迭代?

感謝您的幫助。

解決方案

PHP遞歸函數解決了這個問題。下面是我用,當我到了可能的無限重複的部分:

function foo($element, $indent=0){ 
    $result .= '<li>'; 
    if($indent > 0){ 
    for($i=1;$i<=$indent;$i++){ 
     $result .= '&nbsp;&nbsp;&nbsp;&nbsp;'; 
    } 
    } 
    $result .= $element['name'].'</li>'; 
    if(isset($element['children']['child'])){ 
    $i++; 
    foreach($element['children']['child'] as $child){ 
    $result .= foo($child, $i); 
    } 
    } 
    return $result; 
}  

$output .= foo($item); 

回答

3

您可以使用此一recursive function。每個程序員都應該知道如何使用遞歸;如果你不這樣做:馬上去學習它!

你基本上想要做的就是創建一個函數,我們稱之爲foo(),它在輸入時需要一個項目。 foo會做兩件事情:

  1. 輸出當前項目
  2. 對於每一個孩子,與孩子作爲輸入調用自身。

正如我所說,創建遞歸函數是非常有用的,你應該學習和運用這個工具。例如,您可以使用遞歸的深度向foo發送第二個參數,以便輸出具有不同縮進的子項。

1

在僞代碼,遞歸遍歷節點的功能可能是這個樣子:

function traverse(node) 
{ 
    print(node); 

    if(node.hasChildren()) { 
     foreach(node.children as child) { 
      traverse(child); 
     } 
    } 
} 

希望幫助! :)

相關問題