PHP: Utilisation simplexml en boucle à tous les niveaux d'un fichier XML
Question
J'ai une fonction qui utilise SimpleXML pour revenir au premier niveau des noeuds dans un fichier XML et écrire dans une liste non ordonnée:
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> </ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a></li>'."\n";
}//end foreach
$html .= '</ul>'."\n";
return $html;
}// printAssetMap()
XML J'utilise, qui a imbriqué noeuds:
<?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>
Maintenant, je commence à ajouter des nœuds enfants des noeuds que je suis en retour. Y at-il un moyen de boucle à travers tous les niveaux de nœuds enfants dans un fichier xml, même si je ne sais pas combien de niveaux il y a, et les ajouter à ma liste?
La solution
Donc, fondamentalement, ce que vous devez faire est une fonction qui prend chaque enfant <asset/>
du nœud actuel, construit le HTML vérifie si le nœud actuel a <asset/>
les enfants de son propre et garde récursion plus profondément l'arbre.
Voici comment vous pouvez le faire:
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> </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;
}
Par ailleurs, je me attends à une fonction nommée « PRintX » pour réellement Imprimer ou quelque chose d'écho, plutôt que de le retourner. Peut-être que vous devriez nommer ces fonctions « buildX »?
Autres conseils
vous devez utiliser une fonction récursive. voici un exemple qui affiche un tableau de XML. Il est de la documentation PHP - http://www.php.net/manual /en/ref.simplexml.php . Vous pouvez modifier cette option pour sortir une liste.
<?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;
}
?>
retourne un tableau avec tous les nœuds du document.