Красивый принтер Python XML с lxml - PullRequest
17 голосов
/ 23 февраля 2011

После чтения из существующего файла с «уродливым» XML и внесения некоторых изменений, приятная печать не работает. Я пробовал etree.write(FILE_NAME, pretty_print=True).

У меня есть следующий XML:

<testsuites tests="14" failures="0" disabled="0" errors="0" time="0.306" name="AllTests">
    <testsuite name="AIR" tests="14" failures="0" disabled="0" errors="0" time="0.306">
....

И я использую это так:

tree = etree.parse('original.xml')
root = tree.getroot()

...    
# modifications
...

with open(FILE_NAME, "w") as f:
    tree.write(f, pretty_print=True)

Ответы [ 5 ]

44 голосов
/ 08 марта 2012

Для меня эта проблема не была решена до тех пор, пока я не заметил этот маленький кусочек:

http://lxml.de/FAQ.html#why-doesn-t-the-pretty-print-option-reformat-my-xml-output

Короткая версия:

Прочитать в файле с помощью этой команды:

>>> parser = etree.XMLParser(remove_blank_text=True)
>>> tree = etree.parse(filename, parser)

Это «сбросит» уже существующий отступ, позволяя выводу правильно генерировать свой отступ. Тогда pretty_print как обычно:

>>> tree.write(<output_file_name>, pretty_print=True)
9 голосов
/ 23 февраля 2011

Ну, в соответствии с API документами , в модуле lxml etree нет метода "write". У вас есть несколько вариантов получения довольно напечатанной XML-строки в файл. Вы можете использовать метод tostring так:

f = open('doc.xml', 'w')
f.write(etree.tostring(root, pretty_print=True))
f.close()

Или, если ваш источник ввода не идеален и / или вам нужно больше ручек и кнопок для настройки выхода, вы можете использовать одну из оболочек python для библиотеки libid.

http://utidylib.berlios.de/

import tidy
f.write(tidy.parseString(your_xml_str, **{'output_xml':1, 'indent':1, 'input_xml':1}))

http://countergram.com/open-source/pytidylib

from tidylib import tidy_document
document, errors = tidy_document(your_xml_str, options={'output_xml':1, 'indent':1, 'input_xml':1})
f.write(document)
6 голосов
/ 23 февраля 2011
fp = file('out.txt', 'w')
print(e.tree.tostring(...), file=fp)
fp.close()
2 голосов
/ 03 января 2013

Я не уверен, почему другие ответы не упоминали об этом. Если вы хотите получить корень xml, существует метод с именем getroot(). Надеюсь, я ответил на ваш вопрос (хотя и немного поздно).

tree = et.parse(xmlFile)
root = tree.getroot()
0 голосов
/ 17 июля 2018

Вот ответ, исправленный для работы с Python 3:

from lxml import etree
from sys import stdout
from io import BytesIO

parser = etree.XMLParser(remove_blank_text = True)
file_obj = BytesIO(text)
tree = etree.parse(file_obj, parser)
tree.write(stdout.buffer, pretty_print = True)

где text - код xml в виде последовательности байтов.

...