Pregunta

Se supone que XML es estricto, por lo que hay algunos caracteres unicode que no están permitidos en XML. Sin embargo, estoy tratando de trabajar con Feeds RSS que a menudo contienen estos personajes de todos modos, y me gustaría evitar los errores de análisis de los personajes inválidos o recuperarlos con gracia de ellos y presentar el documento de todos modos.

Vea un ejemplo aquí (el 21 de marzo de todos modos): http://feeds.feedburner.com/chrisblattman

¿Cuál es la forma recomendada de manejar Unicode en la alimentación XML? ¿Detectar los caracteres y sustituir en bytes nulos, editar el analizador o algún otro método?

¿Fue útil?

Solución

Parece que la alimentación RSS contenía un personaje de pestaña vertical \x0c que es ilegal según la especificación XML 1.0.

Mi consejo es filtrar los caracteres ilegales antes de pasar los datos a expatriarse, en lugar de intentar atrapar errores y recuperarse. Aquí hay una rutina para filtrar los caracteres Unicode que son ilegales. Lo probé en tu chrisblattman.xml RSS Feed:

import re
from xml.parsers import expat

# illegal XML 1.0 character ranges
# See http://www.w3.org/TR/REC-xml/#charsets
XML_ILLEGALS = u'|'.join(u'[%s-%s]' % (s, e) for s, e in [
    (u'\u0000', u'\u0008'),             # null and C0 controls
    (u'\u000B', u'\u000C'),             # vertical tab and form feed
    (u'\u000E', u'\u001F'),             # shift out / shift in
    (u'\u007F', u'\u009F'),             # C1 controls
    (u'\uD800', u'\uDFFF'),             # High and Low surrogate areas
    (u'\uFDD0', u'\uFDDF'),             # not permitted for interchange
    (u'\uFFFE', u'\uFFFF'),             # byte order marks
    ])

RE_SANITIZE_XML = re.compile(XML_ILLEGALS, re.M | re.U)

# decode, filter illegals out, then encode back to utf-8
data = open('chrisblattman.xml', 'rb').read().decode('utf-8')
data = RE_SANITIZE_XML.sub('', data).encode('utf-8')

pr = expat.ParserCreate('utf-8')
pr.Parse(data)

Actualizar: Aquí está una página de Wikipedia Acerca de la validez del carácter XML. Mi regexp anterior filtra el rango de control C1, pero es posible que desee permitir que esos personajes dependan de su aplicación.

Otros consejos

Puedes intentar Hermosa sopaque puede analizar documentos HTML/XML incluso si no están bien formados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top