Transformer un fichier XML en dataframe pandas suppose de choisir un parser, une stratégie d’extraction et un niveau de contrôle sur la structure du document. Le résultat dépend moins du code lui-même que du moteur XML utilisé et de la façon dont on cible les nœuds. Cet article mesure les écarts de performance entre les approches courantes pour parse XML using Python, puis détaille les points techniques qui font la différence sur des fichiers réels.
Comparatif des parsers XML disponibles en Python avec pandas
Trois options reviennent dans la plupart des projets : le module xml.etree.ElementTree (bibliothèque standard), la bibliothèque lxml, et la fonction pandas.read_xml introduite dans pandas. Chacune implique un compromis entre simplicité, vitesse et capacité XPath.
| Critère | ElementTree (stdlib) | lxml | pandas.read_xml |
|---|---|---|---|
| Installation | Aucune (inclus dans Python) | pip install lxml | Inclus dans pandas (lxml recommandé) |
| Support XPath | Limité (sous-ensemble basique) | Complet (XPath 1.0) | Complet si lxml est le backend |
| Gestion des namespaces | Manuelle (dict de préfixes) | Native via nsmap | Paramètre namespaces= |
| Vitesse sur gros fichiers | Modérée | Nettement supérieure | Dépend du parser choisi |
| Conversion directe en DataFrame | Non (boucle manuelle) | Non (boucle manuelle) | Oui (une ligne de code) |
Des benchmarks sur des corpus de documents réglementaires montrent que le passage de BeautifulSoup à un parsing basé sur lxml peut multiplier la vitesse par un facteur de 8 à 20 sur des flux XML de type holdings financiers. Sur d’autres structures XML, le gain attendu se situe entre 5 et 15 fois.
pandas.read_xml accepte un paramètre parser qui bascule entre etree et lxml. Quand lxml est installé, pandas l’utilise par défaut, ce qui explique pourquoi les performances de read_xml s’alignent sur celles de lxml dans la majorité des cas.

XPath et namespaces : les deux pièges du parsing XML en Python
La plupart des erreurs de parsing ne viennent pas du code mais de l’expression XPath ou de la gestion des namespaces. Un fichier XML avec un namespace par défaut (xmlns= »… ») rend tous les nœuds invisibles si la requête XPath ne le déclare pas explicitement.
Cibler les bons nœuds avec XPath
Le paramètre xpath de pandas.read_xml attend par défaut ./*, ce qui sélectionne les enfants directs de la racine. Pour un XML imbriqué, il faut descendre dans l’arborescence. Avec lxml comme backend, on peut utiliser des expressions complexes (prédicats, axes, fonctions). En revanche, le parser etree ne supporte qu’un sous-ensemble limité de XPath.
Un fichier SEC Form 13F, par exemple, nécessite de cibler les éléments infoTable via un XPath incluant le namespace. La requête ressemble à //ns:infoTable avec un dictionnaire {'ns': 'http://...'} passé au paramètre namespaces.
Construire le dictionnaire de namespaces
Avec lxml, on récupère le namespace par défaut via root.nsmap[None]. Ce namespace doit ensuite être associé à un préfixe arbitraire dans le dictionnaire transmis à XPath ou à pandas.read_xml. Oublier cette étape est la première cause de dataframes vides après parsing.
Validation et gestion des erreurs avant conversion en dataframe
Un fichier XML récupéré par API ou scraping peut être malformé, incomplet ou servir du HTML par erreur. Alimenter directement pandas.read_xml sans vérification produit des exceptions peu explicites.
Quatre contrôles permettent d’éviter la majorité des problèmes :
- Vérifier le code HTTP de la réponse (status_code == 200) avant tout traitement du contenu
- Contrôler le Content-Type du fichier reçu : refuser text/html quand on attend application/xml
- Encadrer l’appel à ET.fromstring() ou lxml.etree.parse() dans un bloc try/except ParseError pour intercepter les XML malformés
- Pour une validation structurelle, charger un schéma XSD avec lxml.etree.XMLSchema et appeler validate() sur le document avant de construire le dataframe
Cette séquence de vérifications ajoute quelques lignes de code mais évite les dataframes corrompus silencieusement, un problème fréquent dans les pipelines ETL automatisés.

pandas.read_xml : paramètres clés pour un dataframe propre
La fonction read_xml expose plusieurs paramètres qui structurent directement les colonnes du dataframe résultant. Les deux plus déterminants sont elems_only et attrs_only.
Quand elems_only=True, seuls les sous-éléments texte deviennent des colonnes. Les attributs XML sont ignorés. À l’inverse, attrs_only=True ne conserve que les attributs de chaque nœud. Ce choix dépend de la structure du fichier source : un XML orienté attributs (comme certains exports de bases de données SQL) nécessite attrs_only, tandis qu’un XML orienté éléments (flux RSS, documents réglementaires) fonctionne mieux avec elems_only.
Le paramètre names permet de renommer les colonnes à la volée, ce qui évite une étape supplémentaire de nettoyage. Le paramètre dtype force le typage dès la lecture, ce qui est préférable à une conversion post-import sur des colonnes numériques lues comme chaînes.
iterparse pour les fichiers volumineux
Sur des fichiers XML de plusieurs centaines de mégaoctets, charger l’arbre complet en mémoire devient problématique. Le paramètre iterparse de read_xml accepte un dictionnaire qui mappe des balises à des listes de sous-éléments ou attributs à extraire. Le parsing se fait alors en streaming, nœud par nœud, sans construire l’arbre DOM complet.
Cette approche réduit considérablement la consommation mémoire. Elle impose toutefois de connaître précisément la structure du fichier, puisqu’on ne peut plus naviguer librement dans l’arborescence via XPath.
Quel parser choisir selon la taille et la complexité du fichier XML
Pour un fichier XML simple de quelques milliers de lignes, sans namespace, pandas.read_xml avec le backend etree suffit. Aucune dépendance externe, une ligne de code, un dataframe prêt à l’analyse.
Dès que le fichier inclut des namespaces, des structures imbriquées ou dépasse quelques dizaines de mégaoctets, lxml devient le choix par défaut. La compatibilité XPath complète et le gain de performance justifient l’installation d’une dépendance supplémentaire.
Pour des pipelines de données en production qui ingèrent des flux XML quotidiens (API financières, données réglementaires, exports de bases SQL ou Azure), la combinaison lxml + validation XSD + iterparse constitue la chaîne la plus robuste. Le schéma XSD garantit que les données respectent la structure attendue avant toute insertion dans le dataframe, ce qui élimine les erreurs silencieuses en aval.
Le choix du parser détermine aussi la maintenabilité du code. Un script basé sur ElementTree avec des boucles manuelles peut fonctionner, mais il devient fragile dès que la structure XML évolue. pandas.read_xml centralise extraction et conversion en un appel unique, ce qui réduit la surface de maintenance.

