Estoy tratando de crear un documento xml en python, sin embargo, algunas de las cadenas con las que estoy trabajando están codificadas en unicode. ¿Hay alguna manera de crear un nodo de texto usando xml.dom.minidom usando cadenas unicode? ¿Hay otro módulo que pueda usar?

Gracias.

1
Jordan 23 oct. 2009 a las 05:27

3 respuestas

La mejor respuesta

En teoría, por los documentos :

el DOMString definido en la recomendación se asigna a una cadena Python o cadena Unicode. Las aplicaciones deberían poder manejar Unicode siempre que se devuelva una cadena desde el DOM.

Por lo que debería estar bien con una cadena Unicode o una cadena Python (utf-8 es la codificación predeterminada en XML).

En la práctica, en Python 2, a veces he tenido problemas con las cadenas Unicode en xml.dom (me he cambiado casi por completo de él a ElementTree hace un tiempo, así que no estoy seguro de que los problemas sigan ahí en las últimas versiones de Python 2).

Si encuentra problemas al usar cadenas Unicode directamente, creo que querrá probar cadenas codificadas en su lugar, por ejemplo, thedoc.createTextNode(u'pié'.encode('utf-8')).

En Python 3, por supuesto, str s son Unicode, por lo que todo es bastante diferente a este respecto ;-).

3
Alex Martelli 23 oct. 2009 a las 15:06

¿Hay alguna manera de crear un nodo de texto usando xml.dom.minidom usando cadenas unicode?

Sí, createTextNode siempre toma cadenas Unicode. El modelo de texto del conjunto de información XML es Unicode, como puede ver:

>>> doc= minidom.parseString('<a>b</a>')
>>> doc.documentElement.firstChild.data
u'b'

Así que:

>>> doc.createTextNode(u'Hell\xF6') # OK
<DOM Text node "u'Hell\xf6'">

Minidom le permite colocar cadenas no Unicode en el DOM, pero si lo hace y contienen caracteres no ASCII, aparecerá un recorte más adelante:

>>> doc.documentElement.appendChild(doc.createTextNode('Hell\xF6')) # Wrong, not Unicode string
<DOM Text node "'Hell\xF6'">

>>> doc.toxml()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/xml/dom/minidom.py", line 45, in toxml
    return self.toprettyxml("", "", encoding)
  File "/usr/lib/python2.6/xml/dom/minidom.py", line 60, in toprettyxml
    return writer.getvalue()
  File "/usr/lib/python2.6/StringIO.py", line 270, in getvalue
    self.buf += ''.join(self.buflist)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

Esto supone que "codificado en Unicode" quiere decir que está utilizando cadenas Unicode. Si quiere decir algo más, como si tuviera cadenas de bytes en una codificación UTF-8, debe convertir esas cadenas de bytes en cadenas Unicode antes de colocarlas en el DOM:

>>> b= 'Hell\xc3\xb6'    # Hellö encoded in UTF-8 bytes
>>> u= b.decode('utf-8') # Proper Unicode string Hellö
>>> doc.documentElement.appendChild(doc.createTextNode(u))
>>> doc.toxml()
u'<?xml version="1.0" ?><a>bHell\xf6</a>' # correct!
1
bobince 23 oct. 2009 a las 12:33

Los objetos dom parecen tener un argumento de codificación, consulte 20.7.1 de los documentos de Python. Lea la nota al pie también; tenga cuidado de usar la cadena de codificación adecuada.

1
Nick T 23 oct. 2009 a las 01:49