Files
training.python.beginner/documentation/08-text-files-xml.md
Steve Kossouho 086da10d79 Update chapters
Updated chapters 2, 6, 8, 9 and 11.
2025-07-11 21:36:41 +02:00

126 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
</CATALOG>
```
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 types-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]{.naming}, où l'on référence des éléments par rapport à leur "chemin" dans le document
- Méthode [ElementPath]{.naming}, proposée par LXML via les méthodes `find` et `findall`
La plus simple des méthodes disponibles consiste à se baser sur le XPATH pour trouver des éléments :
```python {.numberLines}
from lxml import etree
root = 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 = root.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
root = 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 = root.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/)