在 Python 中写入 .xml 并带有漂亮的打印和编码声明
Write .xml in Python with pretty print and encoding declaration
我必须创建一个 .xml 文件,其中包含漂亮的打印和编码声明。它应该看起来像这样:像这样:
<?xml version='1.0' encoding='utf-8'?>
<main>
<sub>
<name>Ana</name>
<detail />
<type>smart</type>
</sub>
</main>
我知道如何获得漂亮的印刷品和声明,但不是同时获得。
要获得 UTF-8 声明,但没有漂亮的打印,我使用下面的代码:
f = open(xmlPath, "w")
et.write(f, encoding='utf-8', xml_declaration=True)
f.close()
但是如果我想得到漂亮的打印,我必须将xml树转换成字符串,我会丢失声明。我使用此代码:
from xml.dom import minidom
xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")
with open(xmlPath, "w") as f:
f.write(xmlstr.encode('utf-8'))
f.close()
使用最后一个代码,我得到了漂亮的打印,只是第一行是:
<?xml version="1.0" ?>
我不妨将其替换为
<?xml version='1.0' encoding='utf-8'?>
但我不认为这是最符合 Python 风格的方法。
我使用 xml 模块,我不想安装额外的模块,因为脚本必须来自具有标准 Python 的各种计算机 运行。但如果不行的话,我会安装其他模块。
稍后编辑:
最后,在 Lenz 的帮助下,我使用了这个:
#ET=lxml.etree
xmlPath=os.path.join(output_folderXML ,"test.xml")
xmlstr= ET.tostring(root, encoding='UTF-8', xml_declaration=True, pretty_print=True)
with open(xmlPath, "w") as f:
f.write(xmlstr)
f.close()
我需要知道在 "w" 模式下将 "tostring" 方法的结果写入 .xml 文件是否安全,而不是 "wb"。
正如我在下面的一条评论中所说,使用 "wb" 在记事本中打开 xml 文件时,我没有得到漂亮的打印,但是使用 "w",我可以。
另外,我检查了以"w"模式编写的xml文件,其中有“ü”等特殊字符。
我只需要一个合格的意见,我所做的在技术上是可以的。
最优雅的解决方案当然是使用第三方库 lxml,它被广泛使用——有充分的理由。
它在 tostring()
方法中同时提供 pretty_print
和 xml_declaration
参数,因此您可以同时获得两者。 API 与您现在似乎正在使用的 std-lib ElementTree 非常接近。这是一个例子:
>>> from lxml import etree
>>> doc = etree.parse(xmlPath)
>>> print etree.tostring(doc, encoding='UTF-8', xml_declaration=True,
pretty_print=True)
<?xml version='1.0' encoding='UTF-8'?>
<main>
<sub>
<name>Ana</name>
<detail/>
<type>smart</type>
</sub>
</main>
不过,我理解您只想使用 "included batteries"。
据我所知,xml.etree.ElementTree
无法自动更改缩进。
但是 minidom
变通方法有一个同时获得漂亮打印和完整声明的解决方案:使用 toprettyxml()
方法的 encoding
参数!
>>> doc = minidom.parseString(ET.tostring(root))
>>> print doc.toprettyxml(encoding='utf8')
<?xml version="1.0" encoding="utf8"?>
<main>
<sub>
<name>Ana</name>
<detail/>
<type>smart</type>
</sub>
</main>
(请注意,返回的字符串已经过编码,您应该将其写入以二进制模式 ("wb"
) 打开的文件,无需进一步编码。)
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()
这可能会在不使用 lxml 等外部库的情况下解决您的问题
经过一番努力并阅读了大量丑陋的代码后,我想出了这个简单但又
使用 lxml
lybrary 的 E-Factory 编写缩进 XML 文件的有效解决方案。
此解决方案是提供的其他解决方案的集合,但使用 E-Factory 实现,对谁来说它更具可读性和 Pythonic
from lxml import etree, builder
E = builder.ElementMaker()
the_doc = E.root(
E.data(
E.field1('Text...', name='field.one.name', id="field-id"),
E.field2('Text...', name='field.two.name', id="field-id"),
E.field3(
E.subfield1('Text...', name='subfield.one.name', id="field-id"),
E.subfield2('Text...', name='subfield.two.name', id="field-id"),
)
)
)
# Handling the Pretty print
pprinted_xml = etree.tostring(the_doc, encoding='UTF-8', xml_declaration=True,
pretty_print=True)
# Creating the XML file
with open('test.xml', 'wb') as f:
f.write(pprinted_xml)
结果
<?xml version='1.0' encoding='UTF-8'?>
<root>
<data>
<field1 name="field.one.name" id="field-id">Text...</field1>
<field2 name="field.two.name" id="field-id">Text...</field2>
<field3>
<subfield1 name="subfield.one.name" id="field-id">Text...</subfield1>
<subfield2 name="subfield.two.name" id="field-id">Text...</subfield2>
</field3>
</data>
</root>
我必须创建一个 .xml 文件,其中包含漂亮的打印和编码声明。它应该看起来像这样:像这样:
<?xml version='1.0' encoding='utf-8'?>
<main>
<sub>
<name>Ana</name>
<detail />
<type>smart</type>
</sub>
</main>
我知道如何获得漂亮的印刷品和声明,但不是同时获得。 要获得 UTF-8 声明,但没有漂亮的打印,我使用下面的代码:
f = open(xmlPath, "w")
et.write(f, encoding='utf-8', xml_declaration=True)
f.close()
但是如果我想得到漂亮的打印,我必须将xml树转换成字符串,我会丢失声明。我使用此代码:
from xml.dom import minidom
xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")
with open(xmlPath, "w") as f:
f.write(xmlstr.encode('utf-8'))
f.close()
使用最后一个代码,我得到了漂亮的打印,只是第一行是:
<?xml version="1.0" ?>
我不妨将其替换为
<?xml version='1.0' encoding='utf-8'?>
但我不认为这是最符合 Python 风格的方法。
我使用 xml 模块,我不想安装额外的模块,因为脚本必须来自具有标准 Python 的各种计算机 运行。但如果不行的话,我会安装其他模块。
稍后编辑:
最后,在 Lenz 的帮助下,我使用了这个:
#ET=lxml.etree
xmlPath=os.path.join(output_folderXML ,"test.xml")
xmlstr= ET.tostring(root, encoding='UTF-8', xml_declaration=True, pretty_print=True)
with open(xmlPath, "w") as f:
f.write(xmlstr)
f.close()
我需要知道在 "w" 模式下将 "tostring" 方法的结果写入 .xml 文件是否安全,而不是 "wb"。 正如我在下面的一条评论中所说,使用 "wb" 在记事本中打开 xml 文件时,我没有得到漂亮的打印,但是使用 "w",我可以。 另外,我检查了以"w"模式编写的xml文件,其中有“ü”等特殊字符。 我只需要一个合格的意见,我所做的在技术上是可以的。
最优雅的解决方案当然是使用第三方库 lxml,它被广泛使用——有充分的理由。
它在 tostring()
方法中同时提供 pretty_print
和 xml_declaration
参数,因此您可以同时获得两者。 API 与您现在似乎正在使用的 std-lib ElementTree 非常接近。这是一个例子:
>>> from lxml import etree
>>> doc = etree.parse(xmlPath)
>>> print etree.tostring(doc, encoding='UTF-8', xml_declaration=True,
pretty_print=True)
<?xml version='1.0' encoding='UTF-8'?>
<main>
<sub>
<name>Ana</name>
<detail/>
<type>smart</type>
</sub>
</main>
不过,我理解您只想使用 "included batteries"。
据我所知,xml.etree.ElementTree
无法自动更改缩进。
但是 minidom
变通方法有一个同时获得漂亮打印和完整声明的解决方案:使用 toprettyxml()
方法的 encoding
参数!
>>> doc = minidom.parseString(ET.tostring(root))
>>> print doc.toprettyxml(encoding='utf8')
<?xml version="1.0" encoding="utf8"?>
<main>
<sub>
<name>Ana</name>
<detail/>
<type>smart</type>
</sub>
</main>
(请注意,返回的字符串已经过编码,您应该将其写入以二进制模式 ("wb"
) 打开的文件,无需进一步编码。)
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()
这可能会在不使用 lxml 等外部库的情况下解决您的问题
经过一番努力并阅读了大量丑陋的代码后,我想出了这个简单但又
使用 lxml
lybrary 的 E-Factory 编写缩进 XML 文件的有效解决方案。
此解决方案是提供的其他解决方案的集合,但使用 E-Factory 实现,对谁来说它更具可读性和 Pythonic
from lxml import etree, builder
E = builder.ElementMaker()
the_doc = E.root(
E.data(
E.field1('Text...', name='field.one.name', id="field-id"),
E.field2('Text...', name='field.two.name', id="field-id"),
E.field3(
E.subfield1('Text...', name='subfield.one.name', id="field-id"),
E.subfield2('Text...', name='subfield.two.name', id="field-id"),
)
)
)
# Handling the Pretty print
pprinted_xml = etree.tostring(the_doc, encoding='UTF-8', xml_declaration=True,
pretty_print=True)
# Creating the XML file
with open('test.xml', 'wb') as f:
f.write(pprinted_xml)
结果
<?xml version='1.0' encoding='UTF-8'?>
<root>
<data>
<field1 name="field.one.name" id="field-id">Text...</field1>
<field2 name="field.two.name" id="field-id">Text...</field2>
<field3>
<subfield1 name="subfield.one.name" id="field-id">Text...</subfield1>
<subfield2 name="subfield.two.name" id="field-id">Text...</subfield2>
</field3>
</data>
</root>