简体   繁体   English

Python 3 将ElementTree.dump()的output保存到xml文件?

[英]Python 3 save the output of ElementTree.dump() to xml file?

I have this xml file located at path "C:\Program Files (x86)\Microsoft SQL Server\100\Setup Bootstrap\Log\20210331_124249\Datastore_GlobalRules\Datastore_Discovery.xml", it is a one-line-only xml file, you can view it here . I have this xml file located at path "C:\Program Files (x86)\Microsoft SQL Server\100\Setup Bootstrap\Log\20210331_124249\Datastore_GlobalRules\Datastore_Discovery.xml", it is a one-line-only xml file, you可以在这里查看

It is pretty ugly and not very readable and hard to get information from it, so I Google searched for a method to beautify the xml file with Python, and I found this question: Pretty printing XML in Python It is pretty ugly and not very readable and hard to get information from it, so I Google searched for a method to beautify the xml file with Python, and I found this question: Pretty printing XML in Python

The first two answers didn't give me what I wanted, the printed xml is still ugly, but the third answer did give me what wanted:前两个答案没有给我想要的东西,打印出来的 xml 仍然很难看,但第三个答案确实给了我想要的东西:

from xml.etree import ElementTree

def indent(elem, level=0):
    i = "\n" + level*"  "
    j = "\n" + (level-1)*"  "
    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 subelem in elem:
            indent(subelem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = j
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = j
    return elem        

xml = ElementTree.parse('C:/Program Files (x86)/Microsoft SQL Server/100/Setup Bootstrap/Log/20210331_124249/Datastore_GlobalRules/Datastore_Discovery.xml').getroot()
indent(xml)
ElementTree.dump(xml)

This is the output: output.xml这是 output: output.xml

However I can't redirect the output to an xml file;但是我无法将 output 重定向到 xml 文件;

I first tried to use this method:我首先尝试使用这种方法:

out = open('C:/Output.xml','w')
out.write(ElementTree.dump(xml))
out.close()

It gave this error:它给出了这个错误:

TypeError: write() argument must be str, not None

Tried this:试过这个:

xml.write('C:/output.xml')

It gave this error:它给出了这个错误:

AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'write'

If I use this:如果我使用这个:

ElementTree.dump(xml).write('C:/output.xml')

Results this error:结果此错误:

AttributeError: 'NoneType' object has no attribute 'write'

How can I redirect the output of ElementTree.dump(xml) to an xml file?如何将 ElementTree.dump(xml) 的 output 重定向到 xml 文件? I am sorry if this question is too trivial but I am very new to Python, I don't know much, how can I do this?如果这个问题太琐碎,我很抱歉,但我对 Python 很陌生,我不太了解,我该怎么做? Any help is truly appreciated.任何帮助都非常感谢。


PS About how I got the output file, I copy-pasted the output from the console window. PS关于我如何获得output文件,我从控制台window复制粘贴了output。

The dump method dumps the output to sys.stdout you could use the lxml module which has a built in pretty print feature. dump方法将 output 转储到sys.stdout您可以使用具有内置漂亮打印功能的 lxml 模块。

from lxml import etree

data = r"""<a><b>hello</b><c>world</c><d><e>foo</e><f>bar</f></d></a>"""
tree = etree.fromstring(data)
print(etree.tostring(tree, pretty_print=True).decode())

OUTPUT OUTPUT

<a>
  <b>hello</b>
  <c>world</c>
  <d>
    <e>foo</e>
    <f>bar</f>
  </d>
</a>

However if you did want to use only ElementTree since its built in and use your own func, then you need to call the tostring method not dump.但是,如果您确实只想使用 ElementTree,因为它是内置的并使用您自己的 func,那么您需要调用 tostring 方法而不是转储。

from xml.etree import ElementTree

def indent(elem, level=0):
    i = "\n" + level*"  "
    j = "\n" + (level-1)*"  "
    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 subelem in elem:
            indent(subelem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = j
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = j
    return elem

data = r"""<a><b>hello</b><c>world</c><d><e>foo</e><f>bar</f></d></a>"""
tree = ElementTree.fromstring(data)
indent(tree)
print(ElementTree.tostring(tree).decode())

but as you see its not actually as pretty as it should be, not everything is nested correctly但正如您所见,它实际上并不像应有的那样漂亮,并非所有内容都正确嵌套

OUTPUT OUTPUT

<a>
  <b>hello</b>
<c>world</c>
<d>
    <e>foo</e>
  <f>bar</f>
  </d>
</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM