<?php
/*------------------------------*/
/*
Titre : Convertisseur de fichiers XML en Array
Auteur : napalm
Date édition : 21 Jan 2009
Date mise a jour : 26 Sept 2019
Rapport de la maj:
- fonctionnement du code vérifié
Date mise a jour : 03 Mars 2026
Rapport de la maj:
- refactoring du code en PHP 7
- fonctionnement du code vérifié
- refactoring du code en PHP 8
*/
/*------------------------------*/
// Compatible PHP 7.4 ? 8.3
class XmlTree
{
private array $data = [];
/**
* @param string $filename Chemin vers le fichier XML
* @throws Exception Si le fichier ne peut pas être chargé
*/
public function __construct(string $filename)
{
if ($xml === false) {
throw new Exception(
"Impossible de charger le fichier XML : $filename");
}
$this->data = $this->build($xml);
}
/**
* Convertit récursivement un SimpleXMLElement en tableau PHP
*/
private function build(SimpleXMLElement $node): array
{
$result = [];
// Gestion des attributs
if ($node->attributes()->count() > 0) {
foreach ($node->attributes() as $attrName => $attrValue) {
$result['@attributes'][$attrName] = (string)$attrValue;
}
}
// Gestion des enfants
$childrenCount = $node->children()->count();
$textContent = trim((string)$node);
if ($childrenCount === 0) {
// Noeud terminal ? on retourne juste la valeur texte
return $textContent !== '' ? $textContent : $result;
}
// Noeud avec enfants
foreach ($node->children() as $childName => $child) {
$subArray = $this->build($child);
// Si la clé existe déjà ? on passe en mode tableau numérique
if (isset($result[$childName])) {
$childName])) {
$result[$childName] = [$result[$childName]];
}
$result[$childName][] = $subArray;
} else {
$result[$childName] = $subArray;
}
}
return $result;
}
/**
* Récupère une valeur en profondeur avec un nombre variable d'arguments
* Ex: $tree->element('database', 'identification', 'user')
*
* @return mixed|null La valeur trouvée ou null
*/
public function element(): mixed
{
if (empty($args)) {
return null;
}
$current = $this->data;
foreach ($args as $key) {
$current = $current[$key];
} else {
return null;
}
}
return $current;
}
/**
* Pour debug / dump complet
*/
public function getData(): array
{
return $this->data;
}
}
?>
Invité
31 Mars 2011 à 18:36doc php function xml2array($xml) {
if(get_class($xml) != 'SimpleXMLElement') {
if (is_file($xml)) { $xml = simplexml_load_file ($xml); }
elseif (is_string($xml)) { $xml = simplexml_load_string ($xml); }
}
if(!$xml) {
return false;
}
$main = $xml->getName();
$arr = array();
$nodes = $xml->children();
foreach($nodes as $node) {
$nodeName = $node->getName();
$nodeAttributes = $node->attributes();
$attributesArray = array();
foreach($nodeAttributes as $attributeName => $attributeValue) {
$attributesArray[$attributeName] = (string) $attributeValue;
}
$nodeValue = sizeOf($node->children()) == 0 ? trim($node) : xml2array($node);
if(!isSet($arr[$nodeName]['valeur'])) {
$arr[$nodeName]['valeur'] = $nodeValue;
$arr[$nodeName]['attributs'] = $attributesArray;
} else {
if(!is_array($arr[$nodeName]['valeur'])) {
$arr[$nodeName]['valeur'][] = array_shift($arr[$nodeName]);
$arr[$nodeName]['attributs'][] = array_shift($arr[$nodeName]['attributs']);
}
$arr[$nodeName]['valeur'][] = $nodeValue;
$arr[$nodeName]['attributs'][] = $attributesArray;
}
}
return($arr);
}
Invité
29 Mars 2009 à 19:46Code intéréssant mais la classe ne permet pas de l'utiliser dans le cas ou un xml contient plusieurs noeud identifique.
la méthode element devrait plutôt renvoyer un tableau contenant la liste des noeuds voulut.