Python: Unicode и ElementTree.parse

Я пытаюсь перейти на Python 2.7, и поскольку Unicode – это большая сделка, я бы попытался разобраться с ними с файлами и текстами XML и проанализировать их с xml.etree.cElementTree библиотеки xml.etree.cElementTree . Но я столкнулся с этой ошибкой:

 >>> import xml.etree.cElementTree as ET >>> from io import StringIO >>> source = """\ ... <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> ... <root> ... <Parent> ... <Child> ... <Element>Text</Element> ... </Child> ... </Parent> ... </root> ... """ >>> srcbuf = StringIO(source.decode('utf-8')) >>> doc = ET.parse(srcbuf) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 56, in parse File "<string>", line 35, in parse cElementTree.ParseError: no element found: line 1, column 0 

То же самое происходит с использованием io.open('filename.xml', encoding='utf-8') для перехода к ET.parse :

 >>> with io.open('test.xml', mode='w', encoding='utf-8') as fp: ... fp.write(source.decode('utf-8')) ... 150L >>> with io.open('test.xml', mode='r', encoding='utf-8') as fp: ... fp.read() ... u'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n<root>\n <Parent>\n <Child>\n <Element>Text</Element>\n </Child>\n </Parent>\n</root>\n ' >>> with io.open('test.xml', mode='r', encoding='utf-8') as fp: ... ET.parse(fp) ... Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<string>", line 56, in parse File "<string>", line 35, in parse cElementTree.ParseError: no element found: line 1, column 0 

Есть ли что-то в Unicode и ET parsing, которые я здесь отсутствует?

edit : По-видимому, парсер ET не хорошо работает с входным потоком Unicode? Следующие работы:

 >>> with io.open('test.xml', mode='rb') as fp: ... ET.parse(fp) ... <ElementTree object at 0x0180BC10> 

Но это также означает, что я не могу использовать io.StringIO если я хочу анализировать текст в памяти, если я сначала не io.StringIO его в буфере в памяти?

  • Использование Python и lxml для проверки XML на внешний DTD
  • Как удалить узел в xml с помощью ElementTree в Python?
  • Обновление XML-элементов и значений атрибутов с использованием Python etree
  • Проверка XML (.xsd) на схему
  • PyXML на Ubuntu
  • Python, как удалить пробелы из текстовых узлов XML
  • Pythonic Way для создания объединения всех значений, содержащихся в нескольких списках
  • слияние файлов xml с использованием python ElementTree
  • 3 Solutions collect form web for “Python: Unicode и ElementTree.parse”

    Вы не можете использовать

     doc = ET.fromstring(source) 

    в вашем первом примере?

    Ваша проблема в том, что вы кормите ElementTree Unicode, но предпочитаете потреблять байты. Он предоставит вам unicode в любом случае.

    В Python 2.x он может потреблять только байты. Вы можете сказать, в какой кодировке находятся эти байты, но это все. Итак, если вам буквально приходится работать с объектом, представляющим текстовый файл , например io.StringIO , сначала вам нужно будет преобразовать его в нечто другое.

    Если вы буквально начинаете с 2.x- str ( bytes AKA) в кодировке UTF-8, в памяти, как и в вашем примере, используйте xml.etree.cElementTree.XML чтобы разобрать его в XML одним махом, Не беспокойтесь об этом :-).

    Если вам нужен интерфейс, который может обрабатывать данные, которые постепенно считываются из файла, используйте xml.etree.cElementTree.parse с io.BytesIO чтобы преобразовать его в поток в байтах в памяти, а не в строку в памяти персонажи. Если вы хотите использовать io.open , используйте его с флагом b , чтобы вы получали потоки байтов.

    В Python 3.x вы можете передать unicode непосредственно в ElementTree, что немного более удобно, и, возможно, более новая версия ElementTree является более правильной, чтобы это разрешить. Однако вы все еще не захотите, и версия Python 3 все еще принимает байты в качестве входных данных. Вы все равно начинаете с байтов: передавая их напрямую из вашего источника входного сигнала в ElementTree, вы можете позволить ему делать свою кодировку или декодирование разумно внутри механизма синтаксического анализа XML, а также выполнять «на лету» обнаружение объявлений кодирования внутри входного потока, который вы можете использовать с XML, но вы не можете делать с произвольными текстовыми данными. Так что позволить парсеру XML делать работу по расшифровке – это правильное место, чтобы возложить эту ответственность.

    Я столкнулся с той же проблемой, что и в Python 2.6.

    Похоже, что кодировка «utf-8» для cElementTree.parse в версиях Python 2.x и 3.x отличается. В Python 2.x мы можем использовать XMLParser для кодирования unicode. Например:

     import xml.etree.cElementTree as etree parser = etree.XMLParser(encoding="utf-8") targetTree = etree.parse( "./targetPageID.xml", parser=parser ) pageIds = targetTree.find("categorymembers") print "pageIds:",etree.tostring(pageIds) 

    Вы можете обратиться к этой странице для метода XMLParser (раздел «XMLParser»): http://effbot.org/zone/elementtree-13-intro.htm

    Хотя для версии Python 3.x работает следующий метод:

     import xml.etree.cElementTree as etree import codecs target_file = codecs.open("./targetPageID.xml",mode='r',encoding='utf-8') targetTree = etree.parse( target_file ) pageIds = targetTree.find("categorymembers") print "pageIds:",etree.tostring(pageIds) 

    Надеюсь, это может вам помочь.

    Python - лучший язык программирования в мире.