2010-01-24 99 views
4

我有一個使用SimpleXML來返回節點的第一級在一個XML文件,並將其寫入一個無序列表的功能:PHP:通過一個XML文件的各級使用SimpleXML循環

function printAssetMap() { 
    $xml = simplexml_load_file(X_ASSETS); 
    $assets = $xml->asset; 
    $html = '<ul>'."\n"; 
    foreach ($assets as $asset) { 
     $html .= '<li id="asset'.$asset->asset_assetid.'"><ins>&nbsp;</ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a></li>'."\n"; 
    }//end foreach 
    $html .= '</ul>'."\n"; 
    return $html; 
}// printAssetMap() 

XML我使用的,具有嵌套節點:

<?xml version="1.0"?> 
<assets> 
    <asset> 
    <asset_name>Home</asset_name> 
    <asset_url>/home</asset_url> 
    <asset_assetid>1</asset_assetid> 
    </asset> 
    <asset> 
    <asset_name>Projects</asset_name> 
    <asset_url>/projects</asset_url> 
    <asset_assetid>2</asset_assetid> 
    <asset> 
     <asset_name>Portfolio</asset_name> 
     <asset_url>/projects/portfolio</asset_url> 
     <asset_assetid>3</asset_assetid> 
    </asset> 
    <asset> 
     <asset_name>Current Jobs</asset_name> 
     <asset_url>/projects/current-jobs</asset_url> 
     <asset_assetid>4</asset_assetid> 
    </asset> 
    </asset> 
</assets> 

現在,我開始補充說,我目前返回節點的子節點。有沒有辦法循環訪問xml文件中的所有級別的子節點,即使我不知道有多少級別,並將它們添加到我的列表中?

+0

一些示例XML請。 – 2010-01-24 22:55:07

+0

使用XML更新後。 – 2010-01-24 23:00:43

回答

8

所以基本上你需要做的是一個函數,當前節點的每個<asset/>子,構建HTML,然後檢查是否當前節點有它自己的<asset/>孩子,並保持向下遞歸樹更深。

這裏是你如何能做到這一點:

function printAssetMap() 
{ 
    return printAssets(simplexml_load_file(X_ASSETS)); 
} 

function printAssets(SimpleXMLElement $parent) 
{ 
    $html = "<ul>\n"; 
    foreach ($parent->asset as $asset) 
    { 
     $html .= printAsset($asset); 
    } 
    $html .= "</ul>\n"; 

    return $html; 
} 

function printAsset(SimpleXMLElement $asset) 
{ 
    $html = '<li id="asset'.$asset->asset_assetid.'"><ins>&nbsp;</ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a>'; 

    if (isset($asset->asset)) 
    { 
     // has <asset/> children 
     $html .= printAssets($asset); 
    } 

    $html .= "</li>\n"; 

    return $html; 
} 

順便說一句,我希望一個名爲「printX」功能實際上打印或回聲的東西,而不是返回。也許你應該命名這些函數「buildX」?

+0

這是完美的!按照我想要的方式工作,而且它乾淨而簡單。謝謝! – 2010-01-24 23:41:40

1

您需要使用遞歸函數。這裏是一個從XML輸出數組的例子。它來自PHP文檔 - http://www.php.net/manual/en/ref.simplexml.php。你可以修改這個來輸出一個列表。

<?php 
function XMLToArray($xml) 
{ 
    if ($xml instanceof SimpleXMLElement) { 
    $children = $xml->children(); 
    $return = null; 
    } 

    foreach ($children as $element => $value) { 
    if ($value instanceof SimpleXMLElement) { 
     $values = (array)$value->children(); 

     if (count($values) > 0) { 
     $return[$element] = XMLToArray($value); 
     } else { 
     if (!isset($return[$element])) { 
      $return[$element] = (string)$value; 
     } else { 
      if (!is_array($return[$element])) { 
      $return[$element] = array($return[$element], (string)$value); 
      } else { 
      $return[$element][] = (string)$value; 
      } 
     } 
     } 
    } 
    } 

    if (is_array($return)) { 
    return $return; 
    } else { 
    return $false; 
    } 
} 
?> 
0
<?php 
function all_nodes($xml){ 
    $all=array(); 
    function add($node){ 
     array_push($all,$node); 
     foreach($node as $child){ 
      add($child); 
     } 
    } 
    add($xml->documentElement); 
    return $all; 
} 
?> 

這將返回一個包含文檔中所有節點的數組。