XML (eXtensible Markup Language) est un format texte pour stocker et transmettre des données structurées sous forme d'arbre. Sur lui reposent les flux produits des marketplaces et agrégateurs, les formats bancaires et d'échange, les configurations, ainsi que des formats dérivés — les flux RSS et les plans de site. Cet article fait partie de notre panorama général du parsing de documents, centré ici sur le XML.
Comment le XML est construit
Un document XML est un arbre d'éléments. Chaque élément a un nom (balise), éventuellement des attributs, un contenu texte et des éléments imbriqués.
<catalog>
<product id="101" available="true">
<name>Moulin à café</name>
<price currency="EUR">34.90</price>
</product>
<product id="102" available="false">
<name>Bouilloire</name>
<price currency="EUR">21.90</price>
</product>
</catalog>
La différence clé avec JSON : en XML, les données vivent à deux endroits à la fois — dans le texte des éléments (<name>Moulin à café</name>) et dans les attributs (id="101"). Gardez-le en tête : à l'extraction, vous interrogez tantôt le contenu de la balise, tantôt ses attributs.
Sujet à part : les espaces de noms (namespaces). Dans les formats complexes, les balises ressemblent à <g:price> ou <atom:link>, le préfixe étant lié à un URI. Les parseurs exigent de tenir compte du namespace lors de la recherche de nœuds, faute de quoi la sélection revient vide — c'est la cause la plus fréquente du « le parseur ne trouve rien alors que les données sont là ».
Deux approches : arbre en mémoire et lecture en flux
Il existe deux modes d'analyse fondamentalement différents. L'approche DOM construit tout l'arbre en mémoire et offre une navigation commode, y compris via XPath — simple, et adaptée aux fichiers jusqu'à quelques dizaines de mégaoctets. L'approche en flux (SAX / iterparse) lit le fichier par événements, sans le charger entièrement, et devient indispensable pour les exports de centaines de mégaoctets ou de plusieurs gigaoctets. Pour les tâches courantes, le DOM suffit presque toujours ; on passe au flux quand le fichier ne tient plus en mémoire.
Python
La bibliothèque standard fournit le module xml.etree.ElementTree — suffisant pour les cas simples, sans rien installer.
import xml.etree.ElementTree as ET
tree = ET.parse("catalog.xml")
root = tree.getroot()
for product in root.findall("product"):
name = product.find("name").text
price = product.find("price").text
available = product.get("available") # lecture d'un attribut
print(name, price, available)
Pour un travail sérieux, on utilise lxml : plus rapide, plus tolérant au XML « sale », avec un support complet de XPath, namespaces compris.
from lxml import etree
tree = etree.parse("catalog.xml")
# XPath : tous les produits disponibles à moins de 30
for product in tree.xpath("//product[@available='true']"):
name = product.xpath("string(name)")
price = product.xpath("string(price)")
print(name, price)
Si les données arrivent d'une API en XML mais que vous préférez travailler comme avec un dictionnaire, la bibliothèque xmltodict transforme le XML en structures Python imbriquées ordinaires — proche de la façon dont vous traiteriez du JSON.
JavaScript / Node.js
Sous Node, deux solutions dominent. fast-xml-parser convertit le XML en objet sans dépendances externes et va très vite.
const { XMLParser } = require("fast-xml-parser");
const fs = require("fs");
const xml = fs.readFileSync("catalog.xml", "utf-8");
const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "@_" });
const data = parser.parse(xml);
for (const product of data.catalog.product) {
console.log(product.name, product.price["#text"], product["@_available"]);
}
Autre option : xml2js, installée de longue date dans l'écosystème et pratique en traitement asynchrone. Dans le navigateur, le DOMParser intégré permet de parcourir le XML avec les mêmes méthodes qu'un document HTML.
PHP
Pour les documents simples, le SimpleXML intégré est idéal : il expose les éléments comme des propriétés d'objet.
<?php
$xml = simplexml_load_file("catalog.xml");
foreach ($xml->product as $product) {
$name = (string) $product->name;
$price = (string) $product->price;
$available = (string) $product["available"]; // attribut
echo "$name — $price — $available\n";
}
Quand il faut des namespaces, du XPath complexe ou un traitement en flux de gros fichiers, on passe à DOMDocument et XMLReader, dans la même distribution standard de PHP.
Go
La bibliothèque standard de Go inclut le paquet encoding/xml, qui désérialise le XML directement dans des structures via les tags de champs.
package main
import (
"encoding/xml"
"fmt"
"os"
)
type Catalog struct {
Products []struct {
ID string `xml:"id,attr"`
Available string `xml:"available,attr"`
Name string `xml:"name"`
Price string `xml:"price"`
} `xml:"product"`
}
func main() {
data, _ := os.ReadFile("catalog.xml")
var c Catalog
xml.Unmarshal(data, &c)
for _, p := range c.Products {
fmt.Println(p.Name, p.Price, p.Available)
}
}
Erreurs typiques
Les problèmes viennent le plus souvent de l'encodage : si la déclaration annonce un encodage hérité (latin-1/windows-1252) mais que le fichier est lu en UTF-8, les caractères accentués deviennent illisibles — confiez l'encodage au parseur ou convertissez explicitement. Deuxième cause : les namespaces ignorés, qui font que les requêtes XPath renvoient silencieusement un résultat vide. Troisième : tenter de charger un fichier trop gros entièrement en DOM — un export d'un gigaoctet se lit en flux. Enfin, ne parsez pas le XML avec des expressions régulières : le format est imbriqué et récursif, et les regex cassent au premier cas non standard — justifiées pour du texte sans structure (voir parsing de TXT), pas pour du XML.
Si vous avez un schéma d'export non standard, des namespaces cassés ou des fichiers de plusieurs gigaoctets, nous mettons en place le parsing XML adapté à votre format. Et si vos données sources n'arrivent pas en XML pur mais dans ses dérivés, consultez les articles voisins : RSS et sitemap.