Pergunta

Eu tenho uma função que usa o simpxml para retornar o primeiro nível de nós em um arquivo XML e escrevê -lo em uma lista não ordenada:

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 que estou usando, que aninhou nós:

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

Agora, estou começando a adicionar nós filhos dos nós que estou retornando atualmente. Existe uma maneira de percorrer todos os níveis de nós filhos em um arquivo XML, mesmo que eu não saiba quantos níveis existem e adicione -os à minha lista?

Foi útil?

Solução

Então, basicamente, o que você precisa fazer é uma função que leva cada um <asset/> filho do nó atual, constrói o HTML e verifica se o nó atual tem <asset/> filhos próprios e continua se destacando mais fundo na árvore.

Veja como você pode fazer isso:

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

A propósito, eu esperaria que uma função chamada "printx" realmente imprimir Ou ecoar algo, em vez de devolvê -lo. Talvez você deva nomear essas funções "BuildX"?

Outras dicas

Você precisa usar uma função recursiva. Aqui está um exemplo que gera uma matriz de XML. É dos documentos PHP - http://www.php.net/manual/en/ref.simplexml.php. Você pode alterar isso para produzir uma lista.

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

Isso retornará uma matriz com todos os nós no documento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top