Je transforme n xml document avec xslt . En le faisant avec python3, j'ai eu cette erreur suivante. Mais je n'ai aucune erreur avec python2
-> % python3 cstm/artefact.py
Traceback (most recent call last):
File "cstm/artefact.py", line 98, in <module>
simplify_this_dataset('fisheries-service-des-peches.xml')
File "cstm/artefact.py", line 85, in simplify_this_dataset
xslt_root = etree.XML(xslt_content)
File "lxml.etree.pyx", line 3012, in lxml.etree.XML (src/lxml/lxml.etree.c:67861)
File "parser.pxi", line 1780, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:102420)
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.
#!/usr/bin/env python3
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
# -*- coding: utf-8 -*-
from lxml import etree
def simplify_this_dataset(dataset):
"""Create A simplify version of an xml file
it will remove all the attributes and assign them as Elements instead
"""
module_path = os.path.dirname(os.path.abspath(__file__))
data = open(module_path+'/data/ex-fire.xslt')
xslt_content = data.read()
xslt_root = etree.XML(xslt_content)
dom = etree.parse(module_path+'/../CanSTM_dataset/'+dataset)
transform = etree.XSLT(xslt_root)
result = transform(dom)
f = open(module_path+ '/../CanSTM_dataset/otra.xml', 'w')
f.write(str(result))
f.close()
data = open(module_path+'/data/ex-fire.xslt')
xslt_content = data.read()
Cela décode implicitement les octets du fichier en texte Unicode, en utilisant l'encodage par défaut. (Cela peut donner des résultats erronés, si le fichier XML n'est pas dans cet encodage.)
xslt_root = etree.XML(xslt_content)
XML a sa propre gestion et signalisation pour les encodages, le <?xml encoding="..."?>
prologue. Si vous passez une chaîne Unicode commençant par <?xml encoding="..."?>
à un analyseur, l'analyseur aimerait réinterpréter le reste de la chaîne d'octets en utilisant cet encodage ... mais ne le peut pas, car vous avez déjà décodé l'entrée d'octets dans une chaîne Unicode.
Au lieu de cela, vous devez soit passer la chaîne d'octets non décodée à l'analyseur:
data = open(module_path+'/data/ex-fire.xslt', 'rb')
xslt_content = data.read()
xslt_root = etree.XML(xslt_content)
ou, mieux, faites simplement lire l'analyseur directement à partir du fichier:
xslt_root = etree.parse(module_path+'/data/ex-fire.xslt')
Vous pouvez également décoder la chaîne UTF-8 et l'encoder avec ascii avant de la passer à etree.XML
xslt_content = data.read()
xslt_content = xslt_content.decode('utf-8').encode('ascii')
xslt_root = etree.XML(xslt_content)
Je l'ai fait fonctionner simplement en réencodant avec les options par défaut
xslt_content = data.read().encode()