Python - как записать пустой узел дерева в виде пустой строки в XML-файл
Я хочу удалить элементы определенного значения тега, а затем выписать.xml
файл БЕЗ каких-либо тегов для этих удаленных элементов; мой единственный вариант создать новое дерево?
Существует два варианта удаления / удаления элемента:
Чисто() Сбрасывает элемент. Эта функция удаляет все подэлементы, очищает все атрибуты и устанавливает для атрибутов text и tail значение None.
Сначала я использовал это, и это работает с целью удаленияданные от элемента, но у меня все еще остается пустой элемент:
# Remove all elements from the tree that are NOT "job" or "make" or "build" elements
log = open("debug.log", "w")
for el in root.iter(*):
if el.tag != "job" and el.tag != "make" and el.tag != "build":
print("removed = ", el.tag, el.attrib, file=log)
el.clear()
else:
print("NOT", el.tag, el.attrib, file=log)
log.close()
tree.write("make_and_job_tree.xml", short_empty_elements=False)
Проблема в том, чтоxml.etree.ElementTree.ElementTree.write()
по-прежнему записывает пустые теги, несмотря ни на что:
... Параметр short -empty_elements только для ключевых слов управляет форматированием элементов, которые не содержат содержимого. Если True (по умолчанию), они испускаются какодин самозакрывающийся тегв противном случае они испускаются какпара начальных / конечных тегов.
Почему нет возможности просто не распечатывать эти пустые теги! Без разницы.
Тогда я подумал, что могу попробовать
удалить (подэлемент) Удаляет подэлемент с элемента. В отличие от методов find * этот метод сравнивает элементы на основе идентификатора экземпляра, а не значения тега или содержимого.
Но это действует только на дочерние элементы.
Так что мне придетсясделать что-то вроде:
for el in root.iter(*):
for subel in el:
if subel.tag != "make" and subel.tag != "job" and subel.tag != "build":
el.remove(subel)
Но здесь есть большая проблема: я делаю недействительным итератор, удаляя элементы, верно?
Достаточно ли просто проверить, является ли элемент пустым, добавивif subel
?:
if subel and subel.tag != "make" and subel.tag != "job" and subel.tag != "build"
Или мне нужно получать новый итератор для элементов дерева каждый раз, когда я его аннулирую?
Помните: я просто хотел написать файл xml без тегов для пустых элементов.
Вот пример.
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
Допустим, я хочу удалить любое упоминание оneighbor
, В идеале, я хотел бы получить этот вывод после удаления:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
</country>
</data>
Проблема в том, что когда я запускаю код с помощью clear () (см. Первый блок кода выше) и записываю его в файл, я получаю следующее:
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor></neighbor><neighbor></neighbor></country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor></neighbor></country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor></neighbor><neighbor></neighbor></country>
</data>
уведомлениеneighbor
все еще появляется.
Я знаю, что могу легко запустить регулярное выражение для вывода, но должен быть способ (или другой Python API), который делает это на лету, вместо того, чтобы требовать от меня прикоснуться к моей.xml
подать снова.