Le module xml.etree.ElementTree fait partie de la bibliothèque standard Python. Il permet de lire, parcourir et modifier des fichiers XML sans installer de dépendance externe. Malgré sa simplicité apparente, les premières tentatives de lecture XML en Python produisent souvent des résultats silencieusement incorrects : un find() qui renvoie None, un fichier volumineux qui sature la mémoire, ou un encodage qui corrompt les caractères. Cet article isole les erreurs les plus fréquentes et propose une correction directe pour chacune.
Namespace oublié dans find() : le piège silencieux du reading XML Python
La méthode find() d’ElementTree ne lève pas d’exception quand elle ne trouve rien. Elle renvoie simplement None. Ce comportement pose un problème concret quand le fichier XML utilise des namespaces (attribut xmlns sur la balise racine ou sur des éléments enfants).
Lire également : Comment remplacer Python liste append par des approches plus modernes ?
Un appel comme root.find('item') sur un XML contenant <ns:item xmlns:ns="http://exemple.org"> renverra toujours None. Pas d’erreur, pas d’avertissement. Le script continue avec une variable vide, et le bug ne se manifeste que bien plus tard.
Correction avec le dictionnaire de namespaces
La solution consiste à passer un dictionnaire de namespaces en second argument :
Lire également : Python introuvable, pip absent : comment rattraper une mauvaise Install pip installer ?
ns = {'ex': 'http://exemple.org'}root.find('ex:item', ns)
Toujours vérifier la présence de xmlns dans le XML source avant d’écrire la moindre requête find() ou findall(). Les sitemaps XML et les flux RSS utilisent quasi systématiquement des namespaces. Tester sur un fichier local sans namespace, puis passer en production sur un flux réel avec namespace, garantit l’apparition de ce bug.

parse() contre iterparse() : mémoire et fichiers XML volumineux
La fonction ET.parse() charge l’intégralité de l’arbre XML en mémoire. Pour un fichier de configuration de quelques kilo-octets, cela ne pose aucun problème. Pour un export de base de données ou un sitemap de plusieurs centaines de milliers de lignes, le script peut consommer toute la RAM disponible et s’interrompre.
iterparse() traite le XML nœud par nœud sans construire l’arbre complet. La différence d’utilisation mémoire est significative sur les fichiers volumineux.
Schéma de correction avec iterparse()
Le principe repose sur le traitement de chaque élément dès sa fermeture, puis sa suppression immédiate de la mémoire :
for event, elem in ET.iterparse('gros_fichier.xml', events=('end',)): if elem.tag == 'record': # traitement de l'élément elem.clear()
L’appel à elem.clear() libère les données du nœud déjà traité. Sans cette ligne, iterparse() accumule tout en mémoire et perd son intérêt. C’est l’erreur de deuxième niveau : adopter iterparse() sans appeler clear().
Encodage XML en Python : response.content plutôt que response.text
Quand un script Python récupère du XML depuis une URL (API, flux RSS, sitemap distant), la tentation est d’utiliser response.text pour obtenir une chaîne de caractères lisible. Le problème survient quand l’encodage déclaré dans l’en-tête HTTP ne correspond pas à celui déclaré dans le prologue XML.
response.text applique l’encodage détecté par la bibliothèque HTTP (souvent UTF-8 par défaut). Si le XML déclare un autre encodage dans son prologue (<?xml version="1.0" encoding="ISO-8859-1"?>), les caractères accentués seront corrompus ou provoqueront une erreur de parsing.
Travailler sur les octets bruts
La correction consiste à passer response.content (bytes) directement à ET.fromstring() plutôt que response.text (str). ElementTree interprète alors lui-même la déclaration d’encodage du prologue XML et décode correctement le contenu.
Pour les fichiers locaux, le même principe s’applique : ouvrir le fichier en mode binaire ('rb') et laisser le parseur gérer l’encodage est plus fiable que spécifier manuellement un encodage qui pourrait ne pas correspondre.

Parsing d’un XML distant sans gestion d’erreur réseau
Lire un fichier XML local et parser un XML récupéré par HTTP sont deux opérations de nature différente. La seconde introduit des points de défaillance que le parseur XML ne gère pas : timeout réseau, réponse 404, corps de réponse vide, ou contenu HTML au lieu de XML (page d’erreur du serveur).
Passer directement le résultat d’une requête HTTP à ET.fromstring() sans vérification préalable produit des messages d’erreur obscurs. Un ParseError sur du HTML renvoyé à la place du XML attendu est difficile à diagnostiquer sans y avoir pensé en amont.
Checklist de sécurisation avant parsing
- Définir un
timeoutexplicite sur la requête HTTP pour éviter un blocage indéfini du script - Vérifier le code de statut HTTP (
response.status_code == 200) avant toute tentative de parsing - Encadrer l’appel à
ET.fromstring()dans un bloctry/except ET.ParseErrorpour capturer les XML malformés ou les réponses inattendues - Contrôler le
Content-Typede la réponse : s’il contienttext/htmlau lieu deapplication/xml, le contenu n’est probablement pas du XML exploitable
Ces vérifications ajoutent quelques lignes, mais évitent des heures de débogage sur des erreurs intermittentes.
Validation du XML avant extraction de données
Les tutoriels d’introduction au reading XML Python se concentrent sur l’extraction : récupérer un attribut, lire le texte d’un élément, itérer sur des enfants. La question de savoir si le fichier XML est conforme à une structure attendue est rarement abordée à ce stade.
Un XML bien formé n’est pas forcément un XML valide au regard d’un schéma métier. Un fichier peut être syntaxiquement correct (toutes les balises sont fermées) mais contenir des éléments manquants, des attributs renommés ou des types de données incohérents.
La bibliothèque lxml (externe, à installer via pip) permet de valider un document XML contre un schéma XSD avant d’en extraire les données. Cette étape de validation détecte les anomalies structurelles en amont, plutôt que de les découvrir sous forme de None ou d’AttributeError au milieu du traitement.
- Charger le schéma XSD avec
lxml.etree.XMLSchema() - Appeler
schema.validate(doc)qui renvoie un booléen - Consulter
schema.error_logpour obtenir le détail des écarts entre le XML et le schéma
Valider avant d’extraire réduit le temps de débogage de façon très nette, surtout quand le XML provient d’une source externe dont le format peut évoluer sans préavis.
Le reading XML en Python avec ElementTree couvre la majorité des cas d’usage courants. Les cinq erreurs décrites ici (namespace ignoré, mauvais choix entre parse et iterparse, encodage mal géré, absence de gestion réseau, validation manquante) représentent la quasi-totalité des tickets de support liés au parsing XML chez les développeurs qui débutent. Corriger ces points dès le premier script évite de les retrouver en production, où ils coûtent beaucoup plus cher à résoudre.

