Convertisseur de fichiers XML en Array

Classe de parsing xml permettant de convertir l'arborescence d'un fichier XML en collection (Array à plusieurs dimensions), avec SimpleXML.

Idéal pour l'utilisation de fichiers de configuration en XML.

Améliorations:

  • Typage strict (PHP 7.4+ / 8+)
  • Gestion explicite des attributs (@attributes)
  • Meilleure gestion des nœuds multiples (tableaux numériques quand nécessaire)
  • Exception en cas de fichier invalide
  • Retour null au lieu de false quand le chemin n’existe pas (plus moderne)

Information sur les mises à jour

Dernière mise à jour :

26 Sept 2019
fonctionnement du code vérifié

03 Mars 2026
refactoring du code en PHP 7
fonctionnement du code vérifié
refactoring du code en PHP 8

17 662  vues
Compatibilité du code
PHP 7 et PHP 8
  code classé dans   XML
  code source classé dans   XML
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
                    
<?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)
{
$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;
}
}
?>
<?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)
{
$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;
}
}
?>

Exemple :

 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
                    
<?php

$xmlContent = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rootElement>
<database>
<host>localhost</host>
<identification mode="base64">
<user>usr</user>
<password>passwd</password>
</identification>
</database>
</rootElement>
XML;

// Pour tester sans fichier physique :
file_put_contents('file.xml', $xmlContent);

try {
$oTree = new XmlTree('file.xml');

// Récupération des variables (même syntaxe qu'avant)
$strHost = $oTree->element('database', 'host');
$strUser = $oTree->element('database', 'identification', 'user');
$strPass = $oTree->element('database', 'identification', 'password');
$strMode = $oTree->element('database', 'identification', '@attributes',
'mode');

echo "Host : " . var_export($strHost, true) . "\n";
echo "User : " . var_export($strUser, true) . "\n";
echo "Password : " . var_export($strPass, true) . "\n";
echo "Mode : " . var_export($strMode, true) . "\n";

// Bonus : voir toute la structure
// var_export($oTree->getData());

} catch (Exception $e) {
echo "Erreur : " . $e->getMessage() . "\n";
}
?>
<?php

$xmlContent = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rootElement>
<database>
<host>localhost</host>
<identification mode="base64">
<user>usr</user>
<password>passwd</password>
</identification>
</database>
</rootElement>
XML;

// Pour tester sans fichier physique :
file_put_contents('file.xml', $xmlContent);

try {
$oTree = new XmlTree('file.xml');

// Récupération des variables (même syntaxe qu'avant)
$strHost = $oTree->element('database', 'host');
$strUser = $oTree->element('database', 'identification', 'user');
$strPass = $oTree->element('database', 'identification', 'password');
$strMode = $oTree->element('database', 'identification', '@attributes',
'mode');

echo "Host : " . var_export($strHost, true) . "\n";
echo "User : " . var_export($strUser, true) . "\n";
echo "Password : " . var_export($strPass, true) . "\n";
echo "Mode : " . var_export($strMode, true) . "\n";

// Bonus : voir toute la structure
// var_export($oTree->getData());

} catch (Exception $e) {
echo "Erreur : " . $e->getMessage() . "\n";
}
?>

      Fonctions du code - Doc officielle PHP

   php.net  
Description
Versions PHP
    array
Crée un tableau
PHP 4, 5, 7 et 8
    array_is_list
Vérifie si un array donné est une liste
(PHP 8 >= 8.1.0)
    array_key_exists
Vérifie si une clé existe dans un tableau
PHP 4, 5, 7 et 8
    echo
Affiche une chaîne de caractères
PHP 4, 5, 7 et 8
    empty
Détermine si une variable est vide
PHP 4, 5, 7 et 8
    file_put_contents
Écrit des données dans un fichier
PHP 5, 7 et 8
    func_get_args
Retourne les arguments d'une fonction sous la forme d'un tableau
PHP 4, 5, 7 et 8
    isset
Détermine si une variable est déclarée et est différente de null
PHP 4, 5, 7 et 8
    is_array
Détermine si une variable est un tableau
PHP 4, 5, 7 et 8
    return
Retourne le controle du programme au module appelant
PHP 4, 5, 7 et 8
    simplexml_load_file
Convertit un fichier XML en objet
PHP 5, 7 et 8
    trim
Supprime les espaces en début et fin de chaîne
PHP 4, 5, 7 et 8
    var_export
Retourne le code PHP utilisé pour générer une variable
PHP 4, 5, 7 et 8

[2]

  • avatar

    Invité

    31 Mars 2011 à 18:36

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

  • avatar

    Invité

    29 Mars 2009 à 19:46

    Code 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.

Minimum 10 mots. Votre commentaire sera visible après validation.


 Autres snippets qui pourraient vous intéresser

Afficher un ARRAY sur plusieurs colonnes

Compatibilité : PHP 5, PHP 7, PHP 8

Code qui permet d'afficher les datas d'un ARRAY sur le nombre de colonne que vous choisissez avec des balises DIV.

Affiche la distance entres 2 villes via un array associatif

Compatibilité : PHP 5, PHP 7, PHP 8

Formulaire qui prend en compte 2 villes et qui calcul la distance entre ces 2 villes. Possibilité d'ajouter des distances.

* Requêtes exécutées avec Recherche Contextuelle

  Les derniers scripts

PHP 8.5.5

logo PHP
Langue langue us
Date 12 Avril
Taille 32 Mo
Catégorie PHP

PHP 8.4.20

logo PHP
Langue langue us
Date 12 Avril
Taille 30 Mo
Catégorie PHP

Serendipity 2.6.0

logo Serendipity
Langue langue fr
Date 11 Avril
Taille 15 Mo
Catégorie Blogs

Drupal 11.3.6

logo Drupal
Langue langue us
Date 11 Avril
Taille 34 Mo
Catégorie CMS

TYPO3 14.2.0

logo TYPO3
Langue langue fr
Date 10 Avril
Taille 38 Mo
Catégorie CMS

Dolibarr ERP 23.0.1

logo Dolibarr ERP
Langue langue fr
Date 09 Avril
Taille 89 Mo
Catégorie Logiciels