Pregunta lxml.etree.XML ValueError para la cadena Unicode


Estoy transformando un xml documento con xslt. Mientras lo hacía con python3 tuve este error siguiente. Pero no tengo ningún error con 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()

5
2018-02-16 04:18


origen


Respuestas:


data = open(module_path+'/data/ex-fire.xslt')
xslt_content = data.read()

Esto decodifica implícitamente los bytes en el archivo al texto Unicode, usando la codificación predeterminada. (Esto podría dar resultados incorrectos, si el archivo XML no está en esa codificación).

xslt_root = etree.XML(xslt_content)

XML tiene su propio manejo y señalización para codificaciones, el <?xml encoding="..."?> prólogo. Si pasa una cadena Unicode comenzando con <?xml encoding="..."?> para un analizador, el analizador le gustaría volver a interpretar el resto de la cadena de bytes usando esa codificación ... pero no puede, porque ya ha decodificado la entrada de bytes a una cadena Unicode.

En su lugar, debe pasar la cadena de bytes sin codificar al analizador:

data = open(module_path+'/data/ex-fire.xslt', 'b')
xslt_content = data.read()
xslt_root = etree.XML(xslt_content)

O, mejor, simplemente haz que el analizador lea directamente del archivo:

xslt_root = etree.parse(module_path+'/data/ex-fire.xslt')

7
2018-02-16 16:14



También puede decodificar la cadena UTF-8 y codificarla con ascii antes de pasarla a etree.XML

 xslt_content = data.read()
 xslt_content = xslt_content.decode('utf-8').encode('ascii')
 xslt_root = etree.XML(xslt_content)

5
2018-06-25 20:56



Preguntas populares