Вставка новых строк в xml файл, созданный с помощью xml.etree.ElementTree в python
Я создал файл xml с помощью xml.etree.ElementTree в python. Затем я использую
tree.write(filename, "UTF-8")
чтобы записать документ в файл.
Но когда я открываю имя файла с помощью текстового редактора (vi on linux), между тегами нет новых строк. Все это одна большая линия.
Как я могу записать документ в "довольно печатном" формате, чтобы между всеми тегами xml появились новые строки (и, надеюсь, отступы и т.д.)?
Спасибо!
Ответы
Ответ 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, причем количество вкладок указывает количество вкладок, отображаемых в выходных данных.