Как разбирать строки в Юникоде с помощью мини-диска?

Я пытаюсь разобрать кучу xml файлов с библиотекой xml.dom.minidom, чтобы извлечь некоторые данные и поместить их в текстовый файл. Большинство XML файлов идут хорошо, но для некоторых из них я получаю следующую ошибку при вызове minidom.parsestring():

UnicodeEncodeError: кодек ascii не может кодировать символ u '\ u2019' в позиции 5189: порядковый номер не в диапазоне (128)

Это происходит и для некоторых других символов, отличных от ascii. Мой вопрос: какие у меня варианты? Должен ли я каким-то образом убрать/заменить все те неанглийские символы, прежде чем разбираться с XML файлами?

Ответ 1

Попробуйте его декодировать:

> print u'abcdé'.encode('utf-8')
> abcdé

> print u'abcdé'.encode('utf-8').decode('utf-8')
> abcdé

Ответ 2

Minidom напрямую не поддерживает синтаксический анализ строк Unicode; это то, что исторически имело плохую поддержку и стандартизацию. Многие инструменты XML распознают только потоки байтов, которые могут потреблять XML-парсер.

Если у вас есть простые файлы, вы должны либо прочитать их как строки байтов (не Unicode!), и передать это на parseString(), либо просто использовать parse(), который будет читать файл напрямую.

Ответ 3

Если ваша строка - 'str':

xmldoc = minidom.parseString(u'{0}'.format(str).encode('utf-8'))

Это сработало для меня.

Ответ 4

Я знаю, что O.P спрашивал о разборе строк, но у меня было такое же исключение при написании модели DOM в файл через Document.writexml(...). Если люди с этой (связанной) проблемой приземлится здесь, я предложу свое решение.

Мой код, который бросал UnicodeEncodeError, выглядел так:

with tempfile.NamedTemporaryFile(delete=False) as fh:
    dom.writexml(fh, encoding="utf-8")

Обратите внимание, что параметр "encoding" влияет только на заголовок XML и не влияет на обработку данных. Чтобы исправить это, я изменил его на:

with tempfile.NamedTemporaryFile(delete=False) as fh:
    fh = codecs.lookup("utf-8")[3](fh)
    dom.writexml(fh, encoding="utf-8")

Это обернет дескриптор файла экземпляром encodings.utf_8.StreamWriter, который обрабатывает данные как UTF-8, а не ASCII, и UnicodeEncodeError ушел. У меня появилась идея прочитать источник xml.dom.minidom.Node.toprettyxml(...).

Ответ 5

Я встречаюсь с этой ошибкой несколько раз, и мой хакерский способ справиться с этим - это просто сделать это:

def getCleanString(word):   
   str = ""
   for character in word:
      try: 
         str_character = str(character)
         str = str + str_character
      except:
         dummy = 1 # this happens if character is unicode
   return str

Конечно, это, вероятно, глупый способ сделать это, но он выполняет работу для меня, и мне не стоит ничего в скорости.