Lire un fichier XML en Python semble simple : la bibliothèque standard fournit xml.etree.ElementTree, prête à l’emploi sans installation. La vraie difficulté commence quand on compare les approches disponibles, leurs performances et surtout leurs limites de sécurité, un point que la plupart des tutoriels francophones survolent.
Comparatif des modules Python pour lire du XML
Plusieurs modules coexistent dans l’écosystème Python pour parser du XML. Le choix dépend du volume de données, du besoin en XPath et du niveau de confiance accordé au fichier source.
| Module | Installation | XPath | Sécurité (données non fiables) | Cas d’usage principal |
|---|---|---|---|---|
| xml.etree.ElementTree | Bibliothèque standard | Partiel (sous-ensemble XPath) | Non sécurisé par défaut | Fichiers de configuration, petits flux |
| lxml | pip install lxml | Complet (XPath 1.0) | Non sécurisé par défaut | Documents volumineux, transformations XSLT |
| xml.dom.minidom | Bibliothèque standard | Non | Non sécurisé par défaut | Manipulation DOM classique |
| xml.sax | Bibliothèque standard | Non | Non sécurisé par défaut | Fichiers très volumineux (parsing événementiel) |
| defusedxml | pip install defusedxml | Via ElementTree | Sécurisé (blocage entités externes) | Toute source non fiable (API, scraping) |
Le point commun entre ElementTree, lxml, minidom et SAX : aucun n’est sécurisé par défaut pour des données externes. La documentation officielle de Python le mentionne explicitement et oriente vers defusedxml pour bloquer les attaques de type XXE (XML External Entity) et « Billion Laughs ».

ElementTree en pratique : lire et parcourir un fichier XML
ElementTree reste le point d’entrée recommandé pour un débutant qui travaille avec des fichiers XML locaux et fiables. Voici la logique de base.
Charger le fichier et accéder à la racine
Le code minimal tient en trois lignes. On importe le module, on parse le fichier, puis on récupère l’élément racine.
import xml.etree.ElementTree as ETtree = ET.parse('donnees.xml')root = tree.getroot()
La variable root donne accès à toute l’arborescence du document. Chaque nœud possède un tag (nom de balise), un texte (contenu) et des attributs accessibles via un dictionnaire.
Parcourir les éléments enfants
Pour itérer sur les éléments enfants directs de la racine :
for child in root: print(child.tag, child.attrib)
Pour chercher un élément précis dans toute l’arborescence, la méthode findall() accepte un sous-ensemble de la syntaxe XPath :
for item in root.findall('.//produit'): print(item.find('nom').text)
Cette syntaxe suffit pour extraire des données d’un fichier de configuration, d’un export de base de données ou d’un sitemap.
Vulnérabilité XPath corrigée dans les versions récentes de Python
Un bug de performance lié aux requêtes XPath avec prédicats d’indice (comme [1] ou [last()]) pouvait provoquer un déni de service sur des documents contenant un grand nombre de nœuds frères avec la même balise. Cette vulnérabilité, identifiée sous le code CVE-2026-6879, a été corrigée dans Python 3.10.21, 3.11.16 et 3.12.14.
Les méthodes find(), findall() et iterfind() utilisent désormais un algorithme qui évite le comportement quadratique sur ces cas précis. Pour un débutant, la leçon est concrète : maintenir Python à jour protège aussi le code de parsing XML.
Parsing XML sécurisé avec defusedxml
Dès que le fichier XML provient d’une source externe (API web, formulaire utilisateur, flux RSS tiers), les modules standard deviennent un risque. Le module defusedxml fournit des remplacements directs pour ElementTree, minidom, SAX et pulldom.
L’installation se fait en une commande :
pip install defusedxml
Le code change à peine. On remplace l’import :
from defusedxml.ElementTree import parsetree = parse('donnees_externes.xml')
Avec ce seul changement, trois types d’attaques sont bloqués par défaut :
- Les entités externes (XXE), qui permettent à un attaquant de lire des fichiers sur le serveur ou d’effectuer des requêtes réseau
- L’attaque « Billion Laughs », qui fait exploser la mémoire en imbriquant des définitions d’entités récursives
- Les accès réseau déclenchés au moment du parsing, potentiellement exploitables pour du SSRF (Server-Side Request Forgery)
Pour un projet personnel sur des fichiers locaux, ElementTree standard suffit. Pour tout développement exposé à des données non fiables, defusedxml est le choix par défaut recommandé par la documentation officielle.

SAX ou ElementTree : quel module pour un fichier XML volumineux
ElementTree charge l’intégralité du document en mémoire. Sur un fichier de quelques mégaoctets, c’est transparent. Sur un export XML de plusieurs centaines de mégaoctets, la consommation mémoire devient un problème.
Le module xml.sax fonctionne différemment : il lit le fichier en flux (parsing événementiel) et déclenche des callbacks à chaque ouverture ou fermeture de balise. La mémoire utilisée reste constante quelle que soit la taille du fichier.
En revanche, SAX impose un style de programmation plus verbeux. Il faut définir une classe handler qui hérite de ContentHandler et implémenter les méthodes startElement, endElement et characters. Pour un débutant, le code est nettement moins lisible qu’avec ElementTree.
ElementTree propose un compromis avec la méthode iterparse(), qui combine parsing incrémental et API simple :
for event, elem in ET.iterparse('gros_fichier.xml'): if elem.tag == 'produit': print(elem.find('nom').text) elem.clear()
L’appel à elem.clear() libère la mémoire de chaque élément traité. Cette approche offre un bon équilibre entre lisibilité du code et gestion mémoire pour les fichiers volumineux.
Trois erreurs fréquentes en reading XML avec Python
- Oublier les namespaces : un fichier XML avec des préfixes (
ns:balise) nécessite de passer un dictionnaire de namespaces àfindall(), sinon la recherche ne retourne rien - Confondre
find()etfindall(): le premier retourne le premier élément correspondant (ouNone), le second retourne une liste. Accéder à.textsur un résultatNoneprovoque uneAttributeError - Ne pas fermer la boucle avec
elem.clear()lors d’uniterparse(): sans cette ligne, l’arbre entier reste en mémoire et l’avantage du parsing incrémental disparaît
Le parsing XML en Python repose sur un petit nombre de méthodes (parse, getroot, find, findall, iterparse) qui couvrent la grande majorité des cas. La seule décision réellement structurante reste la sécurité : ElementTree pour les fichiers locaux fiables, defusedxml pour tout le reste.


