Подтвердить что ты не робот

Вставка новых строк в xml файл, созданный с помощью xml.etree.ElementTree в python

Я создал файл xml с помощью xml.etree.ElementTree в python. Затем я использую

tree.write(filename, "UTF-8") 

чтобы записать документ в файл.

Но когда я открываю имя файла с помощью текстового редактора (vi on linux), между тегами нет новых строк. Все это одна большая линия.

Как я могу записать документ в "довольно печатном" формате, чтобы между всеми тегами xml появились новые строки (и, надеюсь, отступы и т.д.)?

Спасибо!

4b9b3361

Ответ 1

Самое простое решение, которое, я думаю, переключается на библиотеку lxml. В большинстве случаев вы можете просто изменить свой импорт с import xml.etree.ElementTree as etree на from lxml import etree или аналогичный.

Затем вы можете использовать опцию pretty_print при сериализации:

tree.write(filename, pretty_print=True)

(также доступно на etree.tostring)

Ответ 2

Я нашел новый способ избежать новых библиотек и перефразировать xml. Вам просто нужно передать свой корневой элемент этой функции (см. Ниже пояснение):

def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

В экземплярах xml.etree.ElementTree.Element есть атрибут с именем " tail". Этот атрибут может установить строку после node:

"<a>text</a>tail"

Я нашел ссылку с 2004 года о Функции библиотеки элементов, которая использует этот "хвост" для отступов элемента.

Пример:

root = ET.fromstring("<fruits><fruit>banana</fruit><fruit>apple</fruit></fruits>""")
tree = ET.ElementTree(root)

indent(root)
# writing xml
tree.write("example.xml", encoding="utf-8", xml_declaration=True)

Результат на "example.xml":

<?xml version='1.0' encoding='utf-8'?>
<fruits>
    <fruit>banana</fruit>
    <fruit>apple</fruit>
</fruits>

Ответ 3

В ElementTree нет симпатичной поддержки печати, но вы можете использовать другие XML-модули.

Например, xml.dom.minidom.Node.toprettyxml():

Node.toprettyxml([indent=""[, newl=""[, encoding=""]]])

Верните довольно печатную версию документа. indent указывает строку отступа и по умолчанию используется табулятор; newl указывает строку, испущенную в конце каждой строки, и по умолчанию имеет значение \n.

Используйте indent и newl в соответствии с вашими требованиями.

Пример, используя символы форматирования по умолчанию:

>>> from xml.dom import minidom
>>> from xml.etree import ElementTree
>>> tree1=ElementTree.XML('<tips><tip>1</tip><tip>2</tip></tips>')
>>> ElementTree.tostring(tree1)
'<tips><tip>1</tip><tip>2</tip></tips>'
>>> print minidom.parseString(ElementTree.tostring(tree1)).toprettyxml()
<?xml version="1.0" ?>
<tips>
    <tip>
        1
    </tip>
    <tip>
        2
    </tip>
</tips>

>>> 

Ответ 4

В соответствии с этой нитью ваша лучшая ставка будет устанавливать pyXml и использовать это для prettyprint содержимого ElementTree xml ( поскольку ElementTree по-видимому не имеет симпатичного принтера по умолчанию в Python):

import xml.etree.ElementTree as ET

from xml.dom.ext.reader import Sax2
from xml.dom.ext import PrettyPrint
from StringIO import StringIO

def prettyPrintET(etNode):
    reader = Sax2.Reader()
    docNode = reader.fromString(ET.tostring(etNode))
    tmpStream = StringIO()
    PrettyPrint(docNode, stream=tmpStream)
    return tmpStream.getvalue()

Ответ 5

Без использования внешних библиотек вы можете легко получить новую строку между каждым тегом XML в выводе, установив атрибут хвоста для каждого элемента равным '\n'.

Вы также можете указать количество вкладок после новой строки здесь. Тем не менее, в OP-сценариях использования вкладок может быть проще достичь с помощью внешней библиотеки, либо см. Ответ Эрика М. Шпренгеля.

Я столкнулся с той же проблемой при попытке изменить документ XML с помощью xml.etree.ElementTree в Python. В моем случае я анализировал XML файл, очищал определенные элементы (используя Element.clear()), а затем записывал результат обратно в файл.

Для каждого очищенного элемента не было новой строки после его тега в выходном файле.

ElementTree Документация Element.clear() гласит: "Эта функция удаляет все подэлементы, очищает все атрибуты и устанавливает для атрибутов text и tail значение None".

Это заставило меня понять, что атрибуты text и tail элемента были тем, как определялся формат вывода. В моем случае я смог установить для этих атрибутов очищенного элемента те же значения, что и до его очистки. Это конечное значение в конечном итоге стало \n\t для дочерних элементов первого уровня корневого элемента xml, причем количество вкладок указывает количество вкладок, отображаемых в выходных данных.