Vous parsez un fichier XML avec ElementTree, le code fonctionne, puis vous tombez sur un document truffé de préfixes comme soap:, owl: ou rdf:. D’un coup, find() ne renvoie plus rien. Le problème ne vient pas de votre code, mais de la façon dont Python interprète les namespaces XML. Comprendre leur logique change radicalement la lecture de fichiers XML en Python.
Pourquoi ElementTree ignore vos balises namespacées
Quand un fichier XML déclare xmlns:owl="http://www.w3.org/2002/07/owl#", le préfixe owl n’a aucune existence propre. C’est un raccourci lisible pour les humains, rien de plus. Ce qui compte pour le parseur, c’est l’URI complète associée.
A voir aussi : Comment intranet uga LEO simplifie vos démarches administratives ?
ElementTree traduit chaque balise namespacée en notation de Clark : {http://www.w3.org/2002/07/owl#}Class. C’est cette chaîne exacte qu’il faut passer à find() ou findall() pour obtenir un résultat.
Autrement dit, écrire root.findall('owl:Class') provoque une erreur parce que Python ne connaît pas les préfixes XML par défaut. Il attend soit la notation de Clark, soit un dictionnaire de correspondance que vous lui fournissez explicitement.
A découvrir également : Win7 Download ISO : guide complet pour récupérer Windows légalement
Notation de Clark ou dictionnaire de namespaces en Python
Deux approches coexistent pour interroger un XML namespacé avec ElementTree. Chacune a son contexte d’usage.
Notation de Clark directe
Vous écrivez l’URI complète entre accolades, suivie du nom local de la balise :
root.findall('{http://www.w3.org/2002/07/owl#}Class')
L’avantage : aucun mapping à déclarer. L’inconvénient : des lignes longues et difficiles à relire quand le document mélange plusieurs vocabulaires.
Dictionnaire de préfixes passé à find()
Vous créez un dictionnaire Python qui associe un préfixe court à l’URI :
ns = {'owl': 'http://www.w3.org/2002/07/owl#', 'rdfs': 'http://www.w3.org/2000/01/rdf-schema#'}
Puis vous l’utilisez dans chaque appel : root.findall('owl:Class', ns). Le code reste lisible, et le dictionnaire de namespaces centralise toutes les URI en un seul endroit.

Avec la stabilisation de la notation de Clark depuis Python 3.8-3.9, les deux approches fonctionnent de façon fiable sur toutes les méthodes de recherche d’ElementTree.
Lire un XML multi-namespaces sans perdre le fil
Les fichiers XML industriels (SOAP, EPCIS, ISO 20022) empilent parfois cinq ou six namespaces dans un même document. Voici la méthode qui évite le chaos.
Commencez par stocker chaque URI de namespace dans une constante Python en haut de votre script :
NS_SOAP = 'http://schemas.xmlsoap.org/soap/envelope/'NS_BODY = 'http://example.com/api/v1'
Regroupez-les ensuite dans un dictionnaire unique :
NS = {'soap': NS_SOAP, 'api': NS_BODY}
Ce pattern, parfois appelé « namespace pinning », a un effet concret : quand une URI change entre deux versions du schéma, vous ne modifiez qu’une ligne. Le reste du code continue de fonctionner avec les mêmes préfixes.
Les trois réflexes à adopter pour un parsing fiable :
- Toujours ouvrir le fichier XML brut pour repérer les déclarations
xmlnsavant d’écrire la moindre ligne de code Python - Ne jamais copier-coller un préfixe depuis le fichier source en espérant qu’
ElementTreele reconnaisse automatiquement – il ne le fera pas - Tester chaque
findall()sur un petit extrait avant de lancer le parsing complet, pour vérifier que l’URI correspond bien à celle du document
ElementTree ou lxml pour les namespaces complexes
Pour des fichiers simples avec un ou deux namespaces, xml.etree.ElementTree suffit largement. Le module fait partie de la bibliothèque standard, ne nécessite aucune installation, et couvre la majorité des cas courants.
Quand le document croise plusieurs vocabulaires XML ou que vous avez besoin de requêtes XPath avancées (axes, prédicats imbriqués), lxml offre un support XPath complet qu’ElementTree ne propose pas. La bibliothèque lxml accepte les mêmes dictionnaires de namespaces et la même notation de Clark, ce qui facilite la migration.
La tendance actuelle pour les XML fortement namespacés (EPCIS, SOAP, etc.) est de privilégier lxml avec iterparse() pour traiter de gros fichiers sans charger l’arbre entier en mémoire.
Sécurité du parsing XML namespacé
Depuis 2024-2025, plusieurs vulnérabilités ont été publiées sur des parseurs XML Python, y compris minidom et des bibliothèques tierces comme xmltodict. Les bonnes pratiques imposent désormais d’utiliser defusedxml pour tout parsing de données XML non fiables.
Ce module remplace les parseurs standard par des versions qui bloquent les attaques classiques (expansion d’entités, inclusion de fichiers externes). Il s’utilise en remplacement direct :
import defusedxml.ElementTree as ET
Le reste de votre code, y compris la gestion des namespaces, reste identique.

Erreurs fréquentes de namespace avec ElementTree en Python
Certaines erreurs reviennent dans presque tous les projets qui parsent du XML namespacé pour la première fois.
- Oublier le namespace par défaut : quand un document déclare
xmlns="http://example.com/"sans préfixe, chaque balise enfant hérite de cette URI. Unfind('balise')sans namespace ne renverra rien, il faut écrirefind('{http://example.com/}balise') - Confondre le préfixe du fichier XML avec celui du dictionnaire Python : vous pouvez nommer vos clés comme vous voulez dans le dictionnaire, seule l’URI doit correspondre exactement
- Utiliser
register_namespace()en croyant que cela affectefind(): cette fonction ne sert qu’à contrôler les préfixes lors de l’écriture (sérialisation) d’un XML, pas lors de la lecture
La règle à retenir : en lecture XML avec Python, seule l’URI fait foi, jamais le préfixe. Tant que cette distinction reste claire, les namespaces cessent d’être un obstacle et deviennent un simple mécanisme d’adressage. Le code qui en découle est plus prévisible, plus facile à maintenir, et compatible avec n’importe quel schéma XML que vous rencontrerez.

