Пустые строки при использовании minidom.toprettyxml

Я использовал minidom.toprettyxml для приукрашивания моего XML-файла. Когда я создаю файл XML и использую этот метод, все работает, но если я использую его после того, как я изменил файл XML (например, я добавил дополнительные узлы), а затем я пишу его обратно в XML , я получаю пустые строки, каждый раз, когда я его обновляю, я получаю все больше и больше пустых строк...

мой код:

file.write(prettify(xmlRoot))


def prettify(elem):
    rough_string = xml.tostring(elem, 'utf-8') //xml as ElementTree
    reparsed = mini.parseString(rough_string) //mini as minidom
    return reparsed.toprettyxml(indent=" ")

и результат:

<?xml version="1.0" ?>
<testsuite errors="0" failures="3" name="TestSet_2013-01-23 14_28_00.510935" skip="0"     tests="3" time="142.695" timestamp="2013-01-23 14:28:00.515460">




    <testcase classname="TC test" name="t1" status="Failed" time="27.013"/>




    <testcase classname="TC test" name="t2" status="Failed" time="78.325"/>


    <testcase classname="TC test" name="t3" status="Failed" time="37.357"/>
</testsuite>

какие-либо предложения ?

благодаря.


person Igal    schedule 23.01.2013    source источник


Ответы (6)


Я нашел решение здесь: http://code.activestate.com/recipes/576750-pretty-print-xml/

Затем я изменил его, чтобы он принимал строку вместо файла.

from xml.dom.minidom import parseString

pretty_print = lambda data: '\n'.join([line for line in parseString(data).toprettyxml(indent=' '*2).split('\n') if line.strip()])

Вывод:

<?xml version="1.0" ?>
<testsuite errors="0" failures="3" name="TestSet_2013-01-23 14_28_00.510935" skip="0" tests="3" time="142.695" timestamp="2013-01-23 14:28:00.515460">
  <testcase classname="TC test" name="t1" status="Failed" time="27.013"/>
  <testcase classname="TC test" name="t2" status="Failed" time="78.325"/>
  <testcase classname="TC test" name="t3" status="Failed" time="37.357"/>
</testsuite>

Это может помочь вам немного упростить работу с вашей функцией:

def new_prettify():
    reparsed = parseString(CONTENT)
    print '\n'.join([line for line in reparsed.toprettyxml(indent=' '*2).split('\n') if line.strip()])
person Joe    schedule 24.01.2013
comment
Джо, к сожалению, я получаю исключение из синтаксического анализатора, который должен быть строкой или буфером только для чтения, а не элементом - person Igal; 24.01.2013
comment
Джо, просто чтобы было понятно? мне нужно использовать этот код, пока я создаю xml или после того, как он был создан, и он просто удаляет пустые строки? Спасибо. - person Igal; 24.01.2013

Я нашел простое решение этой проблемы, просто изменив последнюю строку вашего prettify(), чтобы она была:

def prettify(elem):
rough_string = xml.tostring(elem, 'utf-8') //xml as ElementTree
reparsed = mini.parseString(rough_string) //mini as minidom
return reparsed.toprettyxml(indent=" ", newl='')
person Sidali Smaili    schedule 20.04.2017

используйте это, чтобы решить проблему с линиями

toprettyxml(indent=' ', newl='\r', encoding="utf-8")

person Giovani Hgo    schedule 07.07.2015
comment
Хотя это может помочь решить проблему, я бы порекомендовал вам более подробно описать, как ваш ответ помогает. - person Wtower; 08.07.2015
comment
newl='\r' действительно решает проблему в Windows, может иметь какое-то отношение к тому, как новые строки обычно пишутся как '\r\n' в Windows - person prusswan; 02.09.2019

У меня такая же проблема с Python 2.7 (32b) на компьютере с Windows 10. Проблема, похоже, заключается в том, что когда python анализирует текст XML в объекте ElementTree, он добавляет некоторые раздражающие переводы строк либо к атрибутам «текст», либо к «хвосту» каждого элемента.

Этот скрипт удаляет такие символы разрыва строки:

def removeAnnoyingLines(elem):
    hasWords = re.compile("\\w")
    for element in elem.iter():
        if not re.search(hasWords,str(element.tail)):
            element.tail=""
        if not re.search(hasWords,str(element.text)):
            element.text = ""

Используйте эту функцию перед «красивой печатью» вашего дерева:

removeAnnoyingLines(element)
myXml = xml.dom.minidom.parseString(xml.etree.ElementTree.tostring(element))
print myXml.toprettyxml()

Это сработало для меня. Я надеюсь, что это работает для вас!

person Ricardo Alejos    schedule 01.06.2017

Вот решение Python3, которое избавляется от уродливой проблемы новой строки (тонны пробелов) и использует только стандартные библиотеки, в отличие от большинства других реализаций.

import xml.etree.ElementTree as ET
import xml.dom.minidom
import os

def pretty_print_xml_given_root(root, output_xml):
    """
    Useful for when you are editing xml data on the fly
    """
    xml_string = xml.dom.minidom.parseString(ET.tostring(root)).toprettyxml()
    xml_string = os.linesep.join([s for s in xml_string.splitlines() if s.strip()]) # remove the weird newline issue
    with open(output_xml, "w") as file_out:
        file_out.write(xml_string)

def pretty_print_xml_given_file(input_xml, output_xml):
    """
    Useful for when you want to reformat an already existing xml file
    """
    tree = ET.parse(input_xml)
    root = tree.getroot()
    pretty_print_xml_given_root(root, output_xml)

Я нашел, как исправить распространенную проблему с новой строкой здесь.

person Josh Correia    schedule 12.02.2020

Проблема в том, что minidom плохо обрабатывает символы новой строки (в Windows). В любом случае, они не нужны, поэтому удаление их из жала является решением:

reparsed = mini.parseString(rough_string) //mini as minidom

заменить

reparsed = mini.parseString(rough_string.replace('\n','')) //mini as minidom

Но имейте в виду, что это решение работает только для Windows.

person DexBG    schedule 02.04.2020