Я начну с вопроса: «Есть ли альтернативный синтаксический анализатор, который я могу использовать, который может быть менее строгим и содержать символы utf-8?»
Все анализаторы XML будут принимать данные, закодированные в UTF-8. Фактически UTF-8 является кодировкой по умолчанию.
XML-документ может начинаться с объявления, подобного этому:
`<?xml version="1.0" encoding="UTF-8"?>`
или как это:
<?xml version="1.0"?>
или вообще не иметь декларации ... в каждом случае парсер будет декодировать документ с использованием UTF-8.
Однако ваши данные НЕ кодируются в UTF-8 ... это, вероятно, Windows-1252 aka cp1252.
Если кодировка не UTF-8, то либо создатель должен включить объявление (или получатель может добавить его заранее), либо получатель может перекодировать данные в UTF-8. Ниже показано, что работает, а что нет:
>>> import xml.etree.ElementTree as ET
>>> from StringIO import StringIO as sio
>>> raw_text = '<root>can\x92t</root>' # text encoded in cp1252, no XML declaration
>>> t = ET.parse(sio(raw_text))
[tracebacks omitted]
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 9
# parser is expecting UTF-8
>>> t = ET.parse(sio('<?xml version="1.0" encoding="UTF-8"?>' + raw_text))
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 47
# parser is expecting UTF-8 again
>>> t = ET.parse(sio('<?xml version="1.0" encoding="cp1252"?>' + raw_text))
>>> t.getroot().text
u'can\u2019t'
# parser was told to expect cp1252; it works
>>> import unicodedata
>>> unicodedata.name(u'\u2019')
'RIGHT SINGLE QUOTATION MARK'
# not quite an apostrophe, but better than an exception
>>> fixed_text = raw_text.decode('cp1252').encode('utf8')
# alternative: we transcode the data to UTF-8
>>> t = ET.parse(sio(fixed_text))
>>> t.getroot().text
u'can\u2019t'
# UTF-8 is the default; no declaration needed