/*------------------------------*/
|
/*
|
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)
|
{
|
$xml = simplexml_load_file($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])) {
|
if (!is_array($result[$childName]) || !array_is_list($result[
|
$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
|
{
|
$args = func_get_args();
|
if (empty($args)) {
|
return null;
|
}
|
|
$current = $this->data;
|
|
foreach ($args as $key) {
|
if (is_array($current) && array_key_exists($key, $current)) {
|
$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.