Le XML reste un format courant dans les flux de données professionnels : factures électroniques, flux RSS, configurations applicatives. Python propose plusieurs bibliothèques pour lire ces fichiers et les convertir en structures exploitables, notamment en JSON. La conversion repose sur un principe direct : chaque nœud XML devient une clé de dictionnaire, et le dictionnaire obtenu se sérialise en JSON via le module standard json.
Anatomie d’un document XML avant le parsing Python
Un fichier XML organise ses données sous forme d’éléments imbriqués, chacun pouvant porter des attributs et contenir du texte ou d’autres éléments enfants. Cette structure arborescente diffère fondamentalement d’un objet JSON plat.
Prenons un exemple minimal :
<catalog><book id="1"><title>Python Basics</title><price>29.99</price></book></catalog>
Le nœud racine catalog contient un élément book avec un attribut id et deux enfants textuels. Lors du parsing, la difficulté technique réside dans le traitement de cet attribut id : faut-il le convertir en clé classique ou le préfixer pour le distinguer du contenu textuel ?
La bibliothèque xmltodict résout ce problème en préfixant chaque attribut par @ dans le dictionnaire produit. Le champ textuel d’un nœud mixte (attributs + texte) reçoit la clé #text. Ce choix de convention facilite la reconstruction inverse (JSON vers XML) si nécessaire.
Parsing XML avec xmltodict : du fichier au dictionnaire Python
Le module xmltodict transforme un document XML en dictionnaire Python ordonné avec une seule fonction : xmltodict.parse(). L’installation se fait via pip (pip install xmltodict).
Voici le code complet pour parser un fichier XML et obtenir un dictionnaire :
import xmltodictwith open("catalog.xml", "r", encoding="utf-8") as f: data = xmltodict.parse(f.read())
La variable data contient maintenant un OrderedDict Python. L’accès aux valeurs suit la syntaxe habituelle des dictionnaires : data["catalog"]["book"]["title"] renvoie "Python Basics".

Un piège fréquent concerne les éléments répétés. Si le XML contient un seul <book>, xmltodict renvoie un dictionnaire. S’il en contient plusieurs, il renvoie une liste. Ce comportement variable casse le code qui attend toujours une liste. La parade consiste à utiliser le paramètre force_list :
data = xmltodict.parse(xml_string, force_list=("book",))
Avec cette option, data["catalog"]["book"] sera toujours une liste, même avec un seul élément.
Conversion du dictionnaire Python en JSON propre
Une fois le XML transformé en dictionnaire, le module standard json de Python prend le relais. La fonction json.dumps() sérialise le dictionnaire en chaîne JSON, tandis que json.dump() écrit directement dans un fichier.
import jsonjson_string = json.dumps(data, indent=2, ensure_ascii=False)
Le paramètre ensure_ascii=False préserve les caractères accentués au lieu de les échapper en séquences Unicode. Le paramètre indent contrôle le formatage pour la lisibilité humaine, mais peut être omis en production pour réduire la taille du fichier.
Pour écrire le résultat dans un fichier JSON encodé en UTF-8 :
with open("catalog.json", "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2)
La distinction entre json.dump et json.dumps se résume à la destination : fichier pour le premier, chaîne en mémoire pour le second. Le reste des paramètres est identique.
Parsing XML avec ElementTree : l’alternative sans dépendance
Le module xml.etree.ElementTree, inclus dans la bibliothèque standard Python, parse le XML sans installation supplémentaire. La contrepartie : il ne produit pas directement un dictionnaire, il faut écrire la logique de conversion.
import xml.etree.ElementTree as ETtree = ET.parse("catalog.xml")root = tree.getroot()
Chaque élément expose ses attributs via .attrib (un dictionnaire), son texte via .text et ses enfants via itération directe. La conversion récursive en dictionnaire nécessite une fonction dédiée :
- Parcourir les enfants de chaque nœud et appeler la fonction récursivement sur chacun d’eux
- Collecter les attributs XML dans le dictionnaire résultant, en les préfixant pour éviter les collisions avec les noms d’éléments enfants
- Gérer les nœuds feuilles (sans enfant) en affectant directement le contenu textuel comme valeur
- Regrouper les éléments portant le même nom dans une liste pour garantir un comportement cohérent
Cette approche demande plus de code, mais offre un contrôle total sur la structure JSON produite. Pour des fichiers XML volumineux, ET.iterparse() permet un parsing incrémental qui limite la consommation mémoire.
Valider le JSON produit avec un schéma JSON Schema
Parser et convertir ne suffit pas dans un pipeline de données. Si le XML source varie (champs manquants, types incohérents), le JSON produit peut casser les traitements en aval. La validation par JSON Schema vérifie la structure et les types avant exploitation.
Des outils comme check-jsonschema s’intègrent directement dans les hooks pre-commit et les pipelines CI. La validation se fait en une commande ou en quelques lignes Python avec des bibliothèques comme fastjsonschema, qui compile le schéma pour des performances accrues à l’exécution.
Un schéma JSON Schema définit les clés attendues, leurs types et les champs obligatoires. Pour un catalogue de livres, il spécifiera que title est une chaîne requise et que price est un nombre. Toute donnée XML mal formée sera rejetée avant d’atteindre la base de données ou l’API.
- Définir un fichier
.jsoncontenant le schéma avec les propriétés, types et contraintes (required,minItems,pattern) - Lancer la validation via
check-jsonschema --schemafile schema.json output.jsonen CI - Intégrer la validation directement dans le script Python pour un retour immédiat lors de la conversion

Encapsulation de xmltodict dans des bibliothèques spécialisées
Une tendance récente consiste à utiliser xmltodict non plus directement dans les scripts, mais encapsulé dans des bibliothèques dédiées à un format précis. Le module rss-parser, par exemple, s’appuie sur xmltodict pour transformer des flux RSS et Atom en dictionnaires Python. Il gère la conversion des attributs XML en sous-dictionnaires avant le passage en JSON.
Ce modèle d’encapsulation présente un avantage concret : la logique de normalisation des données est mutualisée au lieu d’être réécrite dans chaque projet. Les cas particuliers du format (namespaces RSS, éléments optionnels Atom) sont traités une fois dans la bibliothèque spécialisée.
Le choix entre xmltodict brut et une bibliothèque spécialisée dépend du format XML traité. Pour un schéma XML propriétaire ou peu standardisé, le parsing direct reste préférable. Pour un format bien documenté (RSS, SVG, configuration Maven), vérifier si une bibliothèque Python dédiée existe fait gagner du temps et réduit les erreurs de mapping.
La chaîne complète, du fichier XML au JSON validé, tient en quelques dizaines de lignes Python. Le point déterminant reste le traitement des cas limites : attributs versus éléments, nœuds uniques versus répétés, encodage des caractères spéciaux. Maîtriser ces détails produit un JSON exploitable sans retouche manuelle.

