web-dev-qa-db-fra.com

lxml.etree.XML ValueError pour la chaîne Unicode

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()
13
Papouche Guinslyzinho
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')
24
bobince

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)
6
Josh Allemon

Je l'ai fait fonctionner simplement en réencodant avec les options par défaut

xslt_content = data.read().encode()
1
Loki