Lorsqu’on automatise la création d’un corpus, ou tout autre document, structuré en XML, il est important de veiller à générer également une déclaration XML cohérente avec le contenu du fichier. Il y a plusieurs façons d’y parvenir, notamment en faisant appel à bs4
ou à xml.etree.ElementTree
.
Cet article reprend des parties du script présenté dans Produire un corpus web format XML en 15 lignes de code. Celui-ci est disponible sur Github et Gitlab.
Dans cet article consacré à la constitution d’un corpus en web scraping, la déclaration XML avait été ajoutée grâce à BeautifulSoup
de bs4
. Avec une arborescence XML dont la racine correspond à la variable root
, le code se présentait comme suit :
xml_output = ET.tostring(root, encoding="unicode")
pretty_xml = soup(xml_output, "xml").prettify()
C’est lors de l’application de prettify()
que la déclaration XML est générée. Elle apparaît alors comme ceci dans le document :
<?xml version="1.0" encoding="utf-8"?>
Ce n’est pas le seul moyen d’y parvenir. La déclaration XML pourrait être ajoutée lors de l’étape précédente, avec l’argument optionnel xml_declaration=True
de .tostring()
. Attention, simplement ajouter cet argument n’est pas suffisant, et risque de produire une déclaration XML erronée. Ainsi, si on supprime la variable pretty_xml
et remplace l’assignation de la variable xml_output
par la ligne suivante :
xml_output = ET.tostring(root, encoding="unicode", method="xml", xml_declaration=True)
Voici la déclaration qui pourrait être ajoutée au fichier de sortie dans lequel on aura enregistré xml_output
:
<?xml version='1.0' encoding='cp1252'?>
Ce n’est pas satisfaisant, parce que l’encodage des caractères dans le document est bien UTF-8 et non CP12521. En fonction de la façon dont on consulte le document, ce problème d’encodage pourrait passer inaperçu ; par exemple Notepad++2 décode les caractères en UTF-8 malgré la déclaration :
En revanche, le même document lu par un navigateur web ne s’affichera pas correctement, parce que les caractères seront décodés selon le standard d’encodage spécifié dans la déclaration. Exemple avec Firefox3 :
D’après la documentation la valeur par défaut du paramètre encoding
est US-ASCII, mais il semblerait ici que ce soit l’encodage par défaut du système d’exploitation qui ait été récupéré (le résultat ci-dessus a été obtenu en exécutant le script sur une machine sous Windows 10). Si l’encodage de l’OS est identique à celui du corpus, aucun problème. Mais s’il ne l’est pas, il faudra alors modifier la valeur associée à xml_output
pour que l’encodage spécifié dans la déclaration XML soit bien UTF-8 :
xml_output = ET.tostring(root, encoding="utf-8", method="xml", xml_declaration=True).decode("utf-8")
La déclaration ouvrant le document XML est alors la suivante :
<?xml version='1.0' encoding='utf-8'?>
Et bien sûr, les caractères seront maintenant décodés correctement.
Au final, on peut utiliser au choix l’une ou l’autre de ces méthodes, à condition de vérifier soigneusement quels arguments sont passés à tostring()
.
Mais peut-on utiliser “les deux à la fois” ? C’est-à-dire, remplacer cette partie du script téléchargeable :
xml_output = ET.tostring(root, encoding="unicode", method="xml")
pretty_xml = soup(xml_output, "xml").prettify()
Par ceci :
xml_output = ET.tostring(root, encoding="utf-8", method="xml", xml_declaration=True).decode("utf-8")
pretty_xml = soup(xml_output, "xml").prettify()
C’est effectivement possible, à condition qu’il n’y ait pas de conflit d’encodage entre tostring()
, prettify()
et le fichier de sortie. Si tout est bien en UTF-8, il peut y avoir un intérêt à assigner xml_output
et pretty_xml
de cette façon si vous ne souhaitez pas systématiquement utiliser prettify()
: vous pouvez alors écrire indifféremment pretty_xml
ou xml_output
dans le fichier de sortie et il n’y aura pas de problème d’encodage des caractères.
- Aussi appelé Windows-1252, il s’agit de l’encodage de caractères par défaut des OS Windows pour un certain nombre de langues, dont notamment le français et l’anglais. [↩]
- Testé ici avec Notepad++ v7.9.5. [↩]
- Firefox 89.0.2. [↩]
OpenEdition vous propose de citer ce billet de la manière suivante :
Alexander Delaporte (30 juin 2021). Déclaration XML automatique. Tekipaki. Consulté le 11 décembre 2024 à l’adresse https://doi.org/10.58079/up2l