--- title: Manipuler des fichiers texte XML author: Steve Kossouho --- # Découvrir comment décoder des arborescences XML ---- ## Structure d'un fichier XML Le format XML (_Extensible Markup Language_) est un format de texte permettant de représenter des données hiérarchiques (avec un élément principal) arbitraires. Le contenu d'un document de ce type utilise une syntaxe à base de balises telles qu'on les retrouve en SGML ou HTML : ```xml Empire Burlesque Bob Dylan USA Columbia 10.90 1985 ``` Extrait de document d'exemple. [Lien du document](https://www.w3schools.com/xml/cd_catalog.xml) ---- ## Définition de la structure d'un document XML Professionnellement, il peut être intéressant pour un producteur, ou un consommateur de fichiers XML d'avoir accès à un document normalisant le contenu possible d'un fichier XML. Pendant un temps, seules les [DTD](https://fr.wikipedia.org/wiki/Document_type_definition) existaient mais étaient écrites dans un format assez indigeste. En 2001, le [XML Schema](https://fr.wikipedia.org/wiki/XML_Schema) est plus accessible, et certains outils Python sont capables d'utiliser ces documents pour valider une structure XML. ---- ## Utilisation du XML en Python Si l'on connaît la structure d'un document XML, il est possible de le lire facilement en Python. Même si les packages de la bibliothèque standard fonctionnent, ils sont **spécifiquement** indiqués comme sensibles à des attaques de document malicieusement formé (typiquement XML Bomb, attaque sur le système de références en XML). Parmi les autres bibliothèques, la plus utilisée dans l'écosystème Python semble être [LXML](https://lxml.de) ```{.bash .numberLines} pip install lxml # pour installer la bibliothèque externe ``` ---- ### Exemple de démo de LXML Pour naviguer dans un document XML, il existe plusieurs façons de faire : - Méthode récursive, où l'on récupère un élément pour parcourir ses enfants - Méthode XPATH, où l'on référence des éléments par rapport à leur "chemin" dans le document La plus simple des méthodes disponibles consiste à se baser sur le XPATH pour trouver des éléments : ```{.python .numberLines} from lxml import etree tree = etree.parse(r"source.xml") # récupère l'élément racine # Récupérer les éléments de la racine CATALOG qui ont le nom CD items = tree.xpath("/CATALOG/CD") ``` - [Guide complet sur le XPath](https://www.ionos.com/digitalguide/websites/web-development/xpath-tutorial/) - [Exemple plus simple sur le XPath](https://www.w3schools.com/xml/xpath_syntax.asp) ---- ### Parcourir des résultats XPATH Dans l'exemple précédent, nous avons pu récupérer, via une "requête" XPATH, un possible ensemble d'éléments. Ces éléments peuvent être parcourus avec une simple boucle `for`{.python} : ```{.python .numberLines} from lxml import etree tree = etree.parse(r"source.xml") # récupère l'élément racine # Récupérer les éléments de la racine CATALOG qui ont le nom CD items = tree.xpath("/CATALOG/CD") for cd in items: for attribute in cd: # afficher le nom et les attributs, puis le texte print(attribute.tag, attribute.attrib, attribute.text) ``` ---- ## Propriétés des éléments `_ElementTree` Les éléments du modèle de document sont représentés sous la forme d'instances de la classe `_ElementTree`. Pour en extraire des données, de nombreuses méthodes sont documentées officiellement, mais les attributs les plus simples à retenir sont les suivants : - `attrib` (`dict`{.python}) : renvoie les attributs de la balise; - `tag` (`str`{.python}) : renvoie le nom de la balise; - `text` (`str`{.python}) : renvoie le texte direct de la balise. Également, un élément peut être parcouru avec une boucle `for`{.python} et renverra à chaque itération chacun de ses éléments enfants, même si la méthode suivante existe aussi : - `getchildren()`{.python} : renvoie un itérable des éléments enfants. ---- ## Documentation officielle de LXML - [Documentation officielle (en anglais)](https://lxml.de) - [Tutorial LXML par Oxylabs](https://oxylabs.io/blog/lxml-tutorial) - [Sérialiser des objets Python en XML](https://pypi.org/project/lxml-dataclass/)