logo oujood
🔍

Création de fichiers XML depuis MySQL avec les fonctions DOM de PHP : Guide technique complet

Ce guide technique détaillé s'adresse aux développeurs souhaitant maîtriser l'extraction de données depuis une base de données MySQL et leur conversion en fichiers XML structurés. Apprenez à utiliser l'extension DOM de PHP pour générer du XML dynamique, gérer les relations parent-enfant, ajouter des attributs personnalisés et transformer vos données pour des traitements ultérieurs via XSLT.

OUJOOD.COM

Public visé et objectifs pédagogiques


PHP et génération XML dynamique

L'architecture de séparation des couches constitue une pratique fondamentale en développement web moderne. Cette approche méthodologique permet de dissocier complètement la couche de présentation (génération des documents HTML affichés à l'utilisateur) de la couche métier (application des règles d'entreprise et logique applicative via PHP). Cette séparation architecturale garantit que chaque couche peut être modifiée, optimisée ou remplacée indépendamment sans impacter le fonctionnement de l'autre, facilitant ainsi la maintenance et l'évolution de vos applications web.

Dans les exemples pratiques détaillés ci-dessous, les données sont extraites depuis la base de données MySQL et stockées dans un tableau associatif PHP (structure de données composée de paires clé-valeur). Chaque élément de ce tableau est ensuite extrait méthodiquement et transféré vers le fichier XML en cours de construction. Le contenu du tableau associatif est directement déterminé par l'instruction SQL SELECT que vous définissez selon vos besoins métier.

Dans les démonstrations techniques qui suivent, nous explorerons progressivement comment traiter les données provenant d'une table unique, puis comment gérer des données issues de deux tables liées par une relation un-à-plusieurs (parent-enfant). Nous verrons également comment enrichir vos fichiers XML en insérant des données supplémentaires sous forme d'attributs XML, offrant ainsi une flexibilité maximale dans la structuration de vos données.

L'intégralité du code source présenté dans ce tutoriel est disponible en téléchargement dans notre exemple d'application pratique pour faciliter votre apprentissage.

Prérequis techniques et connaissances nécessaires

Pour suivre efficacement ce tutoriel sur la génération de fichiers XML avec PHP, votre environnement de développement doit disposer de l'extension DOM activée dans votre installation PHP. Cette extension, généralement activée par défaut dans les versions récentes de PHP, fournit les classes et méthodes nécessaires pour manipuler des documents XML.

Ce guide suppose que vous possédez une compréhension de base de la syntaxe et structure des fichiers XML. Si vous débutez avec le langage XML, nous vous recommandons vivement de consulter nos tutoriels détaillés sur le langage XML qui couvrent les concepts fondamentaux nécessaires.

Une bonne maîtrise de PHP et MySQL est également indispensable pour comprendre pleinement les techniques de connexion aux bases de données, l'exécution de requêtes SQL et la manipulation des résultats retournés.

Génération XML depuis une table unique : Approche pas à pas

Dans cette première approche technique, le code va extraire le contenu de la variable $resultat_BDD (contenant un nombre quelconque de lignes retournées par la requête SQL, chaque ligne étant composée de paires clé-valeur) et le transformer en une chaîne de caractères XML valide. Cette chaîne XML peut ensuite être soit enregistrée dans un fichier sur le disque, soit transformée dynamiquement en document HTML grâce aux fonctions XSL intégrées à PHP, permettant des transformations XSLT sophistiquées.

La première étape fondamentale consiste à établir la connexion à la base de données MySQL et à exécuter la requête SQL qui récupérera les données à exporter :

  📋 Copier le code

<!-- Connexion à la base de données MySQL et exécution de la requête -->
<?php
// Tentative de connexion au serveur MySQL local
if(!$dbconnect = mysql_connect('localhost', 'user', 'pass')) {
    echo "La connexion au serveur 'localhost' a échoué.";
    exit;
} 
// Sélection de la base de données cible
if (!mysql_select_db('test')) {
    echo "Impossible de se connecter à la base de données 'test'";
    exit;
} 
// Définition du nom de la table et construction de la requête SQL
$table_id = 'nom_table';
$query = "SELECT * FROM $table_id";
// Exécution de la requête et stockage des résultats
$resultat_BDD = mysql_query($query, $dbconnect);
?>

Maintenant que les données sont récupérées depuis MySQL, nous pouvons les transférer vers un document XML structuré. La première action consiste à créer un nouveau document DOM. La commande suivante initialise le numéro de version XML à « 1.0 » et retourne la référence d'objet pour le nouveau document :

// Créer un nouveau document XML avec version 1.0
$document = new DomDocument('1.0');

Le premier élément à créer dans tout document XML valide est l'élément racine (root element). Chaque document XML doit obligatoirement posséder un et un seul élément racine qui englobera tous les autres éléments du document.

Dans cet exemple technique, nous nommerons cet élément « racine », mais vous êtes libre d'utiliser n'importe quel nom descriptif correspondant à votre contexte métier.

Il est important de noter que la création d'un élément nécessite deux opérations distinctes : la création de l'élément avec createElement(), puis son insertion dans le document avec appendChild().

// Créer le nœud racine du document XML
$racine = $document->createElement('racine');
// Insérer le nœud racine dans le document
$racine = $document->appendChild($racine);

Nous sommes maintenant prêts à parcourir et ajouter les données récupérées depuis MySQL. Le code utilise une boucle pour traiter chaque enregistrement retourné par la requête.

Notez que chaque ligne est récupérée sous forme de tableau associatif grâce à mysql_fetch_assoc(), ce qui nous fournit automatiquement une liste de paires « nom_colonne = valeur ». Cette structure de données simplifie considérablement tous les traitements ultérieurs.

// Traiter une ligne à la fois avec une boucle while
while($ligne = mysql_fetch_assoc($resultat_BDD)) {

Pour chaque ligne de la base de données, nous devons créer un nouvel élément XML. Le code ci-dessous crée un élément portant le nom de la table, puis l'insère dans le document comme enfant direct de l'élément racine.

  // Ajouter un nœud pour chaque ligne de données
  $element = $document->createElement($table_id);
  // Insérer comme enfant de la racine
  $element = $racine->appendChild($element);

Ensuite, nous parcourons chaque colonne de la ligne courante et insérons le nom du champ ainsi que sa valeur correspondante. Vous constaterez à quel point un tableau associatif facilite cette opération : nous n'avons pas à nous préoccuper du nombre de colonnes retournées par la requête SQL, ni de leur ordre d'apparition, ni même de leurs noms spécifiques.

  // Parcourir chaque colonne avec foreach
  foreach ($ligne as $nomChamp => $valeurChamp) {

Pour chaque champ, nous créons un nouvel élément XML portant le nom de la colonne, puis nous l'insérons en tant qu'enfant de l'élément de ligne actuel (identifié par la variable $element).

    // Créer un élément pour le champ
    $enfant = $document->createElement($nomChamp);
    // Insérer comme enfant de l'élément ligne
    $enfant = $element->appendChild($enfant);

Il faut maintenant ajouter la valeur du champ sous forme de nœud texte (text node), puis l'insérer comme élément enfant du nœud de champ actuel (identifié par $enfant).

    // Créer un nœud texte contenant la valeur
    $valeur = $document->createTextNode($valeurChamp);
    // Insérer le nœud texte dans l'élément champ
    $valeur = $enfant->appendChild($valeur);

Ces boucles imbriquées continuent leur exécution jusqu'à ce qu'elles aient traité chaque colonne de chaque ligne récupérée depuis la base de données MySQL.

  } // fin foreach - toutes les colonnes traitées
} // fin while - toutes les lignes traitées

La méthode suivante retourne le document XML complètement rempli sous forme de chaîne de caractères, prêt à être utilisé.

// Convertir le document DOM en chaîne XML
$xml_chaine = $document->saveXML();

Dans cet exemple basique, nous affichons simplement les résultats au navigateur du client. Cependant, vous pourriez tout aussi bien effectuer un traitement supplémentaire tel que transmettre cette chaîne XML à un processeur XSLT pour effectuer une transformation vers un autre format de document (par exemple HTML) en utilisant le contenu d'un fichier XSL séparé.

// Afficher le résultat XML
echo $xml_chaine;
?>

Le contenu du fichier XML généré dynamiquement par ce code ressemblera à la structure suivante :

Le document commence toujours par la déclaration XML, spécifiant le numéro de version, immédiatement suivie par l'ouverture du nœud racine.

<?xml version="1.0"?>
<racine>

Pour chaque ligne extraite de la base de données, un élément XML est créé comme enfant direct du nœud racine. Cet élément porte le nom de la table source. Chaque élément ligne dispose d'un élément enfant distinct pour chaque colonne présente dans cette ligne.

Notez que chaque élément colonne contient un nœud texte pour stocker sa valeur, tandis que l'élément ligne lui-même ne contient pas de nœud texte direct.

Cette structure se répète pour chaque colonne de chaque ligne. Après la dernière colonne, vous remarquerez la balise de fermeture de l'élément ligne, après quoi le groupe ligne/colonnes est répété pour chaque enregistrement supplémentaire extrait de la base de données.

<ligne1>
  <colonne1>valeur1</colonne1>
  <colonne2>valeur2</colonne2>
  ............
  <colonneX>valeurX</colonneX>
</ligne1>
<ligne2>
  ............
</ligne2>

La dernière ligne d'un fichier XML valide sert à fermer le nœud racine, complétant ainsi la structure du document.

</racine>

Notez que chaque élément dans le document XML possède une balise d'ouverture et une balise de fermeture au format <element>...</element>. Cette paire de balises identifie le nom du nœud dans l'arborescence hiérarchique du document XML.

Le contenu situé entre ces deux balises constitue un nœud enfant de cet élément. Ce nœud enfant peut être soit un nœud texte (valeur simple), soit un autre élément XML (structure imbriquée).

Vous verrez parfois un élément dans un document XML noté sous la forme <element />. Cette notation signifie que l'élément est vide. XML permet de fusionner les balises d'ouverture et de fermeture en une seule balise auto-fermante lorsqu'un élément ne contient aucun enfant.

Gestion des relations parent-enfant : Tables liées

Dans cet exemple avancé, le code XML généré contiendra les données de deux tables MySQL organisées selon une relation parent-enfant (également appelée relation externe-interne ou un-à-plusieurs). Les éléments de la table enfant seront imbriqués comme nœuds enfants des éléments de la table parent, créant ainsi une structure XML hiérarchique reflétant vos relations de base de données.

Dans le code des requêtes SQL suivant, deux résultats distincts sont produits : $externeResultat pour la table parent et $interneResultat pour la table enfant.

Je commenterai uniquement les portions de code qui présentent des différences significatives par rapport à l'exemple précédent.

  📋 Copier le code

<!-- Établissement de la connexion MySQL pour relation parent-enfant -->
<?php
// Connexion au serveur de base de données
if(!$dbconnect = mysql_connect('localhost', 'user', 'pass')) {
    echo "La connexion au serveur 'localhost' a échoué.";
    exit;
}
// Sélection de la base de données de travail
if (!mysql_select_db('test')) {
    echo "Impossible de se connecter à la base de données 'test'";
    exit;
}
?>

Voici les deux requêtes SQL distinctes pour extraire les données de chacune des deux tables liées :

Dans cet exemple, parent_table représente le nom de la table que nous souhaitons définir comme parent dans la hiérarchie XML :

  📋 Copier le code

<!-- Requête SQL pour extraire les données de la table parent -->
// Définir le nom de la table parent
$exterene_table = 'parent_table';
// Construire la requête SELECT avec clause WHERE
$query = "SELECT * FROM $exterene_table WHERE colonne='valeur'";
// Exécuter la requête et stocker le résultat
$externeResultat = mysql_query($query, $dbconnect);

Ici, child_table représente le nom de la table que nous voulons définir comme enfant dans la structure XML :

  📋 Copier le code

<!-- Requête SQL pour extraire les données de la table enfant -->
// Définir le nom de la table enfant
$interne_table = 'child_table';
// Construire la requête SELECT liée au parent
$query = "SELECT * FROM $interne_table WHERE colonne='valeur'";
// Exécuter la requête et stocker le résultat
$interneResultat = mysql_query($query, $dbconnect);

Nous créons maintenant un nouveau document DOM comme précédemment :

$document = new DomDocument('1.0');

Puis nous ajoutons le nœud racine du document :

  📋 Copier le code

<!-- Création et insertion du nœud racine -->
// Créer l'élément racine
$racine = $document->createElement('racine');
// Attacher la racine au document
$racine = $document->appendChild($racine);

Ensuite, nous ajoutons un nœud pour l'enregistrement unique provenant de la table parent :

  📋 Copier le code

<!-- Création du nœud pour la table parent -->
// Créer un élément portant le nom de la table parent
$exterene = $document->createElement($exterene_table);
// L'insérer comme enfant de la racine
$exterene = $racine->appendChild($exterene);

N'oublions pas d'ajouter chaque valeur de colonne comme élément enfant du nœud $exterene représentant la table parent.

// Récupérer l'enregistrement parent
$ligne = mysql_fetch_assoc($externeResultat);

Nous parcourons maintenant chaque champ parent avec une boucle foreach pour créer les nœuds enfants :

  📋 Copier le code

<!-- Parcours et insertion des champs de la table parent -->
// Itérer sur chaque champ du parent
foreach ($ligne as $nomChamp => $valeurChamp) {
    // Créer un élément pour ce champ
    $enfant = $document->createElement($nomChamp);
    // L'attacher au nœud parent externe
    $enfant = $exterene->appendChild($enfant);
    // Créer un nœud texte pour la valeur
    $valeur = $document->createTextNode($valeurChamp);
    // Insérer la valeur dans l'élément champ
    $valeur = $enfant->appendChild($valeur);
}

Maintenant, nous ajoutons un nœud pour chaque ligne provenant de la table enfant. Cette étape est cruciale pour la hiérarchie XML.

Notez bien que chacune de ces lignes est insérée comme nœud enfant du nœud $exterene (table parent), et non pas directement du nœud $racine. Chaque nœud $interne aura ensuite ses propres valeurs de colonnes insérées comme ses éléments enfants.

Nous traitons toutes les lignes de la table interne en utilisant une boucle while combinée à la boucle foreach vue précédemment :

  📋 Copier le code

<!-- Traitement de tous les enregistrements de la table enfant -->
// Parcourir chaque ligne enfant
while ($ligne = mysql_fetch_assoc($interneResultat)) {
    // Créer un nœud pour cet enregistrement enfant
    $interne = $document->createElement($interne_table);
    // IMPORTANT : l'attacher au parent, pas à la racine
    $interne = $exterene->appendChild($interne);
    // Parcourir chaque champ de l'enregistrement enfant
    foreach ($ligne as $nomChamp => $valeurChamp) {
        // Créer un élément pour ce champ
        $enfant = $document->createElement($nomChamp);
        // L'attacher au nœud enfant interne
        $enfant = $interne->appendChild($enfant);
        // Créer le nœud texte contenant la valeur
        $valeur = $document->createTextNode($valeurChamp);
        // Insérer la valeur dans l'élément
        $valeur = $enfant->appendChild($valeur);
    }
}

Finalement, nous récupérons le document XML complètement construit et l'envoyons au navigateur du client :

  📋 Copier le code

<!-- Conversion et affichage du document XML -->
// Convertir le document DOM en chaîne XML
$xml_string = $document->saveXML();
// Envoyer le résultat au navigateur
echo $xml_string;
?>

Le code ci-dessus génère un fichier XML avec une structure hiérarchique ressemblant à ceci :

  📋 Copier le code

<!-- Structure XML résultante avec relation parent-enfant -->
<?xml version="1.0"?>
<racine>
  <parent_table>
    <colonne1>valeur1</colonne1>
    <colonne2>valeur2</colonne2>
    ............
    <colonneX>valeurX</colonneX>
    <child_table>
      <colonne1>valeur1</colonne1>
      <colonne2>valeur2</colonne2>
      ............
      <colonneX>valeurX</colonneX>
    </child_table>
    <child_table>
      ............
    </child_table>
  </parent_table>
</racine>

Nous obtenons donc une structure XML hiérarchique : <racine> contient <parent_table> qui contient à son tour <child_table>. L'élément <parent_table> possède comme nœuds enfants directs ses valeurs de colonnes ainsi que plusieurs occurrences de <child_table>, créant ainsi une relation parent-enfant claire et structurée.

Ajout d'attributs XML facultatifs : Enrichissement des métadonnées

Il peut s'avérer nécessaire d'inclure des informations supplémentaires ou métadonnées pour certains éléments dans vos données XML. Cette fonctionnalité avancée peut être réalisée grâce à l'utilisation d'attributs XML.

Un attribut XML possède un nom et une valeur. Vous pouvez ajouter un nombre illimité d'attributs à n'importe quel élément. Cette opération doit être effectuée en utilisant la méthode setAttribute() immédiatement après la méthode appendChild() et avant toute autre méthode createTextNode(), comme illustré dans cet extrait de code :

  📋 Copier le code

<!-- Ajout d'attributs XML personnalisés à un élément -->
// Créer l'élément pour le champ
$enfant = $document->createElement($nomChamp);
// L'insérer dans le document
$enfant = $exterene->appendChild($enfant);
// Ajouter le premier attribut avec sa valeur
$enfant->setAttribute('attr1', 'attrval1');
// Ajouter le second attribut avec sa valeur
$enfant->setAttribute('attr2', 'attrval2');
// Créer et insérer le nœud texte
$valeur = $document->createTextNode($valeurChamp);
$valeur = $enfant->appendChild($valeur);

Ces valeurs d'attributs apparaissent dans la balise d'ouverture de l'élément concerné, comme suit :

  📋 Copier le code

<!-- Exemple de rendu XML avec attributs -->
<?xml version="1.0"?>
<racine>
  <some_table>
    <colonne1 attr1="attrval1" attr2="attrval2">valeur1</colonne1>
    <colonne2 attr1="attrval1" attr2="attrval2">valeur2</colonne2>
    <colonne3 attr1="attrval1" attr2="attrval2">valeur3</colonne3>
  </some_table>
</racine>

Notez que vous pouvez insérer des attributs aussi bien pour les éléments représentant des lignes que pour les éléments représentant des colonnes, offrant ainsi une grande flexibilité dans la structuration de vos métadonnées XML.

Gestion des caractères multi-octets et encodage UTF-8

Si vous devez traiter des caractères accentués (comme à, é, è, í, ö et û) ou tout autre caractère spécial non-ASCII dans vos données XML, vous devez configurer l'encodage de caractères du document DOM en UTF-8.

Cette configuration nécessite les deux modifications suivantes dans les exemples de code précédents :

(1) Pour définir l'encodage de caractères du document DOM en UTF-8, vous devez modifier la ligne d'instanciation comme suit :

  // Créer un document DOM avec encodage UTF-8
  $xml_doc = new DomDocument('1.0', 'UTF-8');

(2) Ensuite, effectuez la conversion du jeu de caractères par défaut (consultez la directive default_charset dans votre fichier php.ini) vers UTF-8 en insérant une ligne de conversion comme illustré ci-dessous :

  📋 Copier le code

<!-- Conversion des caractères en UTF-8 pour compatibilité -->
// Parcourir chaque champ de la ligne
foreach ($ligne as $nomChamp => $valeurChamp) {
    // Créer l'élément pour ce champ
    $enfant = $document->createElement($nomChamp);
    // L'insérer dans le document
    $enfant = $interne->appendChild($enfant);
    // IMPORTANT : Convertir la valeur de ISO-8859-1 vers UTF-8
    $valeurChamp = mb_convert_encoding($valeurChamp,'UTF-8','ISO-8859-1');
    // Créer le nœud texte avec la valeur convertie
    $valeur = $document->createTextNode($valeurChamp);
    // Insérer la valeur dans l'élément
    $valeur = $enfant->appendChild($valeur);
} // foreach

Remarque importante : Pour que cette conversion d'encodage fonctionne correctement, vous devez activer les fonctions Chaîne multi-octets (mbstring) dans votre configuration PHP.

chapitre précédent

sommaire

chapitre suivant

Par carabde | Mis à jour le 30 novembre 2025