使用minidom.toprettyxml时空行

时间:2013-01-23 12:23:13

标签: python xml pretty-print minidom

我一直在使用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>

有什么建议吗?

感谢。

6 个答案:

答案 0 :(得分:20)

我在这里找到了一个解决方案: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()])

答案 1 :(得分:3)

我找到了解决这个问题的简单方法,只需更改最后一行即可 你的美化()所以它会是:

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='')

答案 2 :(得分:1)

这是一个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)

我发现了如何解决常见的换行问题here

答案 3 :(得分:0)

用它来解决行

的问题

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

答案 4 :(得分:0)

我在Windows 10机器上遇到与Python 2.7(32b)相同的问题。问题似乎是当python将XML文本解析为ElementTree对象时,它会向每个元素的“text”或“tail”属性添加一些恼人的换行符。

此脚本会删除此类换行符:

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()

它对我有用。我希望它适合你!

答案 5 :(得分:0)

问题在于,minidom无法很好地处理换行符(在Windows上)。 无论如何它都不需要它们,因此将它们从from中移除是解决方案:

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

替换为

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

但是请注意,这是仅适用于Windows的解决方案。