Reading XML python : le guide clair pour débutants francophones

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 ».

Développeur Python analysant un fichier XML sur deux écrans dans un open space professionnel

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 ET
tree = 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 parse
tree = 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.

Adolescent débutant qui apprend la lecture de fichiers XML avec Python sur son lit dans une chambre d'étudiant

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() et findall() : le premier retourne le premier élément correspondant (ou None), le second retourne une liste. Accéder à .text sur un résultat None provoque une AttributeError
  • Ne pas fermer la boucle avec elem.clear() lors d’un iterparse() : 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.

Articles populaires

A PROPOS DU BLOG

Blog du Marketing

Le Blog du Marketing est un site internet, ouvert aux contributions, consacré aux infos et conseils autour du marketing, du webmarketing, mais aussi du secteur de la communication en général.

Il vous sera possible de vous informer sur de nombreux sujets autour de ce secteur, via des articles de nos rédacteurs, que cela soit par exemple à propos du référencement naturel / SEO et du SEM, les audits marketing et études de satisfaction ainsi que sur les stratégies de marketing digital …