2010-01-24 2 views
4

У меня есть функция, которая использует SimpleXML для возврата первого уровня узлов в файле XML и записать его в виде неупорядоченного списка:PHP: Использование SimpleXML для перебора всех уровней файла XML

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, пожалуйста. –

+0

Обновлено сообщение с XML. –

ответ

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

Это прекрасно! Работает именно так, как я этого хотел, и он чист и прост. Спасибо! –

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; 
} 
?> 

Это вернет массив со всеми узлами в документе.

Смежные вопросы