Python - печатать красивый XML, создавать открывающие и закрывающие теги для пустого текста тегов

Я пишу приложение на Python, которое создает ElementTree (XML), а затем записывает его в файл, используя toprettyxml() от minidom;

final_tree = minidom.parseString(ET.tostring(root))
fdout.write(final_tree.toprettyxml(indent = '    ')

Проблема в том, что теги, к которым я не добавляю текст, имеют только один тег, например:

<sometag/>

Я хочу, чтобы это было:

<sometag>
</sometag>

Я хочу сделать это без разбора всей строки (без регулярного выражения). Кто-нибудь знаком с таким способом? Спасибо.


person amitizle    schedule 29.05.2013    source источник
comment
почему это должно быть проблемой?   -  person mata    schedule 29.05.2013
comment
Потому что это должно выглядеть как второй способ.   -  person amitizle    schedule 29.05.2013
comment
Второй имеет новую строку между тегами. Это не то же самое, что пусто.   -  person Janne Karila    schedule 29.05.2013
comment
Да, но почему? Ни один парсер xml не должен иметь проблем с первой формой. С другой стороны, второй не полностью эквивалентен первому, так как содержит пробелы. Во всяком случае, эквивалентом <sometag/> является <sometag></sometag> (без пробелов между ними).   -  person mata    schedule 29.05.2013
comment
Я понимаю, что это требование.   -  person amitizle    schedule 29.05.2013
comment
замените эти теги на ‹tag›‹/tag› или подобные. Это предотвратит их преобразование в emtpy на выходе.   -  person pypat    schedule 29.05.2013
comment
В любом случае красивая печать обычно вводит пробелы.   -  person Alfe    schedule 29.05.2013


Ответы (1)


Поведение жестко запрограммировано в minidom.py (посмотрите на метод writexml() в class Element). Он не предназначен для изменения, но для текущей реализации вы можете исправить его следующим образом:

from xml.dom import minidom

t = minidom.parseString('<a><b></b></a>')

def patcher(method):
  def patching(self, *args, **kwargs):
    old = self.childNodes
    try:
      if not self.childNodes:
        class Dummy(list):
          def __nonzero__(self):  # Python2
            return True
          def __bool__(self):  # Python3
            return True
        old, self.childNodes = self.childNodes, Dummy([])
      return method(self, *args, **kwargs)
    finally:
      self.childNodes = old
  return patching

t.firstChild.__class__.writexml = patcher(t.firstChild.__class__.writexml)

print t.toprettyxml()

Но, конечно, я не могу рекомендовать такой хак.

person Alfe    schedule 29.05.2013
comment
Большое спасибо, в итоге я использовал регулярное выражение. - person amitizle; 29.05.2013
comment
Спасибо @Alfe. Я использовал ваш хак, когда проходил курс nand2tetris, где вы должны точно соответствовать ключу ответа XML. Думаю, я мог бы распечатать этот XML, но мне нравилось оставлять ключ ответа в покое. - person Ben Ogorek; 04.07.2018