2012-03-07 6 views
0

xmlをファイルから読み込み、ツリーのように表示しようとしています。私はPHPを使用しており、以下のように出力を取得したい。 xmlファイルの内容は以下の通りです... PHP XML - 親子関係と同じレベルにあるxmlノードのツリーを構築する方法

<Categories> 

<Category> 
    <Id>1</Id> 
    <Name>Parent 1</Name> 
    <ParentId>1</ParentId> 
    <ParentName>Parent 1</ParentName> 
</Category> 
<Category> 
    <Id>2</Id> 
    <Name>Child 1</Name> 
    <ParentId>1</ParentId> 
    <ParentName>Parent 1</ParentName> 
</Category> 
<Category> 
    <Id>3</Id> 
    <Name>Child 2</Name> 
    <ParentId>1</ParentId> 
    <ParentName>Parent 1</ParentName> 
</Category> 
<Category> 
    <Id>8</Id> 
    <Name>Grand Child 1 -1</Name> 
    <ParentId>2</ParentId> 
    <ParentName>Child 1</ParentName> 
</Category> 

<Category> 
    <Id>12</Id> 
    <Name>Parent 2</Name> 
    <ParentId>12</ParentId> 
    <ParentName>Parent 2</ParentName> 
</Category> 

<Category> 
    <Id>15</Id> 
    <Name>Child 2-1</Name> 
    <ParentId>12</ParentId> 
    <ParentName>Parent 2</ParentName> 
</Category> 

    </Categories> 
</CategoryList> 

私は私がすべてになるだろうどのように...このxmlファイルを読むために(私はそれを読んでする方法を知っている)しかし、次のように私はそれをフォーマットすることはできませんしたいです最上位の親があり、それらの親ノードの子を取得するノードは

編集* ....

<ul> 
<li>Parent 1 
    <ul> 
     <li> Child 1 
      <ul> 
       <li>Grand Child 1 -1</li> 
      </ul> 

     </li> 
     <li> Child 2</li> 
    </ul> 

</li> 
<li>Parent 2 
    <ul> 
     <li>Child 2-1 </li> 
    </ul> 

</li> 

</ul> 

は、任意のヘルプは大歓迎されますしてください(再帰またはので、これまで何を使用して)何私はこれまで行ってきた...

$xml= simplexml_load_string('myxmlstring'); 

get_categories($xml, 0); 

function get_categories($xml, $id) { 

    if ($id==0) 
     $Categories = $xml->xpath('Categories/Category[ParentId=Id]'); 
    else 
     $Categories = $xml->xpath('Categories/Category[ParentId='.$id.' and Id!='.$id.']'); 

    echo '<ul id="catlist'.$id.'">'; 
    foreach($Categories as $Category) { 
     echo "<li>ID: " . $Category->Id . "--Name: " . $Category->Name; 
     get_categories($xml, $Category->Id); 
     echo "</li>"; 

    } 
    echo "</ul>"; 
} 

これが最適な解決策であることを確認したいだけです。または誰かがより良いアイデアを持って来ることができます...

答えて

1

親が多すぎると、親IDだけを入れれば十分です。

各ノードを検索するので、実行時間はO(N )になります。ここで、Nはノードの数です。

これを行うには、次のようなオプションがあります。まず、データをトラバースしてツリー構造(または多少)をトラバースし、その構造と出力ノードをトラバースします。

Output bufferingもここでは良いオプションです。

// init 
$childrenReferences = array(); 
$rootNodes = array(); 
$xmlNodes = array(); 

// gathering structure 
$cats = $xml->getElementsByTagName('Category'); 
for ($i = 0; $i < $cats->length; $i++) { 
    $cat = $cats[$i]; 
    $id = $children->Id; 
    $parentId = $cat->ParentId; 
    $xmlNodes[$id] = $cat; 
    if ($parentId == $id) { 
     $rootNodes []= $id; 
     continue; 
    } 
    if (array_key_exists($parentId, $childrenReferences)) { 
     $childrenReferences[$parentId] []= $id; 
    } else { 
     $childrenReferences[$parentId] = array($id); 
    } 

} 

// output 
function out_nodes($nodes) { 
    global $childrenReferences, $xmlNodes; // this is not required since php 5.3 or something about 
    echo "<ul>"; 
    foreach ($nodes as $id) { 
     $cat = $xmlNodes[$id]; 
     echo "<li>ID: " . $cat->Id . "--Name: " . $cat->Name; 
     if (array_key_exists($id, $childrenReferences)) { // intermediate node 
      out_nodes($childrenReferences[$id]); 
     } 
     echo "</li>"; 
    } 
    echo "</ul>"; 
} 

ob_start(); 
out_nodes($rootNodes); 
ob_end_flush(); 

コードが機能しない、またはコンパイルできない可能性があります。

1

ありがとう。kirilloid ....すごく助かりました。私はいくつかの変更を加えてコードを使用しています... XMLはカールから来ていますが、ParentNameは過剰ですが、私はそれを制御できません。ここに最終的なコードがあります....

$childrenReferences = array(); 
$rootNodesIDs = array(); 
$xmlNodes = array(); 

$dom = new DOMDocument; 
$dom->loadXML($xml); 

$Categories = $dom->getElementsByTagName('Category'); 
$length = $Categories->length; 

for ($i = 0; $i < $length; $i++) { 
    $cat = $Categories->item($i);   //Get the DOMNode 
    $id = $cat->getElementsByTagName('Id')->item(0)->nodeValue; 
    $parentId = $cat->getElementsByTagName('ParentId')->item(0)->nodeValue; 
    $xmlNodes[$id] = $cat;  

    if ($parentId == $id) { 
     $rootNodesIDs []= $id; 
     continue; 
    } 

    if (array_key_exists($parentId, $childrenReferences)) { 
     $childrenReferences[$parentId] []= $id;   
    } else { 
     $childrenReferences[$parentId] = array($id); 
    } 
} 

function out_nodes($rootids) { 
    global $childrenReferences, $xmlNodes; 

    echo "<ul>"; 
    foreach ($rootids as $id) { 
     $cat = $xmlNodes[$id]; 
     echo "<li>ID: " . $cat->getElementsByTagName('Id')->item(0)->nodeValue . "--Name: " . $cat->getElementsByTagName('Name')->item(0)->nodeValue; 
     if (array_key_exists($id, $childrenReferences)) { // intermediate node 
      out_nodes($childrenReferences[$id]); 
     } 
     echo "</li>"; 
    } 
    echo "</ul>"; 
} 

ob_start(); 
out_nodes($rootNodesIDs); 
ob_end_flush(); 
関連する問題