使用漂亮的打印和编码声明在 Python 中编写 .xml

pan*_*nda 6 xml pretty-print utf-8 python-2.7

我必须创建一个具有漂亮打印效果和编码声明的.xml文件。它应该看起来像这样:

\n
<?xml version='1.0' encoding='utf-8'?>\n<main>\n    <sub>\n        <name>Ana</name>\n        <detail />\n        <type>smart</type>\n    </sub>\n</main>\n
Run Code Online (Sandbox Code Playgroud)\n

我知道如何获得漂亮的打印和声明,但不是同时获得。\n要获得 UTF-8 声明,但没有漂亮的打印,我使用以下代码:

\n
f = open(xmlPath, "w")\net.write(f, encoding='utf-8', xml_declaration=True) \nf.close()\n
Run Code Online (Sandbox Code Playgroud)\n

但是如果我想获得漂亮的打印结果,我必须将 xml 树转换为字符串,并且我将丢失声明。我使用这段代码:

\n
from xml.dom import minidom\nxmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="   ")\nwith open(xmlPath, "w") as f:\n    f.write(xmlstr.encode('utf-8'))\n    f.close()\n
Run Code Online (Sandbox Code Playgroud)\n

通过最后的代码,我得到了漂亮的打印结果,只是第一行是:

\n
<?xml version="1.0" ?>\n
Run Code Online (Sandbox Code Playgroud)\n

我不妨将其替换为

\n
<?xml version='1.0' encoding='utf-8'?>\n
Run Code Online (Sandbox Code Playgroud)\n

但我不认为这是最Pythonesque的方法。

\n

我使用 xml 模块,并且不喜欢安装额外的模块,因为该脚本必须使用标准 Python 从不同的计算机上运行。但如果不可能,我会安装其他模块。

\n

稍后编辑:

\n

最后,在 Lenz 的帮助下,我使用了这个:

\n
#ET=lxml.etree\nxmlPath=os.path.join(output_folderXML ,"test.xml")\nxmlstr= ET.tostring(root, encoding='UTF-8', xml_declaration=True, pretty_print=True)\nwith open(xmlPath, "w") as f:\n    f.write(xmlstr)\n    f.close()\n
Run Code Online (Sandbox Code Playgroud)\n

我需要知道以“w”模式而不是“wb”模式将“tostring”方法的结果写入 .xml 文件是否安全。\n正如我在下面的评论之一中所说,使用“wb”当我在记事本中打开 xml 文件时,我没有得到漂亮的打印结果,但使用“w”时,我得到了。\n此外,我还检查了以“w”模式编写的 xml 文件以及“\xc3\”等特殊字符xbc”在那里。\n我只需要一个有说服力的意见,证明我所做的技术上是可以的。

\n

len*_*enz 5

最优雅的解决方案当然是使用第三方库lxml,出于充分的原因,它被大量使用 \xe2\x80\x93 。\n它在方法中同时提供了 apretty_print和一个xml_declaration参数tostring(),因此您可以同时获得两者。而且该 API 与您现在似乎正在使用的 std-lib ElementTree 的 API 非常接近。这是一个例子:

\n\n
>>> from lxml import etree\n>>> doc = etree.parse(xmlPath)\n>>> print etree.tostring(doc, encoding=\'UTF-8\', xml_declaration=True,\n                         pretty_print=True)\n<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<main>\n  <sub>\n    <name>Ana</name>\n    <detail/>\n    <type>smart</type>\n  </sub>\n</main>\n
Run Code Online (Sandbox Code Playgroud)\n\n

不过,我理解您只想使用“附带的电池”的愿望。\n据我所知,xml.etree.ElementTree无法自动更改缩进。\n但minidom解决方法有一个解决方案,可以同时获得漂亮的打印和完整的打印效果。声明:使用方法encoding的参数toprettyxml()

\n\n
>>> doc = minidom.parseString(ET.tostring(root))\n>>> print doc.toprettyxml(encoding=\'utf8\')\n<?xml version="1.0" encoding="utf8"?>\n<main>\n    <sub>\n        <name>Ana</name>\n        <detail/>\n        <type>smart</type>\n    </sub>\n</main>\n
Run Code Online (Sandbox Code Playgroud)\n\n

(请注意,返回的字符串已经编码,您应该将其写入以二进制模式 ( "wb") 打开的文件中,而不需要进一步编码。)

\n


小智 5

from xml.dom import minidom
xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="   ", encoding='UTF-8')
with open(xmlPath, "w") as f:
    f.write(str(xmlstr.decode('UTF-8')))
    f.close()
Run Code Online (Sandbox Code Playgroud)

这可能会解决您的问题,而无需使用 lxml 等外部库