在Python中,美化XML的最佳方法是什么(或者有哪些方法)?
import xml.dom.minidom
dom = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = dom.toprettyxml()
lxml是最近更新的,包含一个漂亮打印函数
import lxml.etree as etree
x = etree.parse("filename")
print etree.tostring(x, pretty_print=True)
请查看lxml教程:http://lxml.de/tutorial.html
print(etree.tostring(x, pretty_print=True, encoding="unicode"))
。只需一行代码即可将结果写入输出文件,无需使用中间变量:etree.parse("filename").write("outputfile", encoding="utf-8")
。 - Thoretree.XMLParser(remove_blank_text=True)
有时可以帮助正确打印。 - oak另一种解决方案是借用这个indent
函数,用于Python 2.5以后内置的ElementTree库。
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
root = ElementTree.parse('/tmp/xmlfile').getroot()
indent(root)
ElementTree.dump(root)
tree.write([filename])
来将其写入文件(其中 tree
是 ElementTree 实例)。 - Bouketree = ElementTree.parse('file) ; root = tree.getroot() ; indent(root); tree.write('Out.xml');
- e-malito您有几个选择。
自带电池,易于使用,输出整齐美观。
但需要 Python 3.9+ 版本。
import xml.etree.ElementTree as ET
element = ET.XML("<html><body>text</body></html>")
ET.indent(element)
print(ET.tostring(element, encoding='unicode'))
BeautifulSoup可能是Python < 3.9中最简单的解决方案。
from bs4 import BeautifulSoup
bs = BeautifulSoup(open(xml_file), 'xml')
pretty_xml = bs.prettify()
print(pretty_xml)
输出:<?xml version="1.0" encoding="utf-8"?>
<issues>
<issue>
<id>
1
</id>
<title>
Add Visual Studio 2005 and 2008 solution files
</title>
</issue>
</issues>
这是我的默认答案。默认参数按原样工作。但文本内容会像嵌套元素一样分散在单独的行中。
带有参数的漂亮输出。
from lxml import etree
x = etree.parse(FILE_NAME)
pretty_xml = etree.tostring(x, pretty_print=True, encoding=str)
产生: <issues>
<issue>
<id>1</id>
<title>Add Visual Studio 2005 and 2008 solution files</title>
<details>We need Visual Studio 2005/2008 project files for Windows.</details>
</issue>
</issues>
这对我来说没有任何问题。
无需外部依赖,但需要进行后处理。
import xml.dom.minidom as md
dom = md.parse(FILE_NAME)
# To parse string instead use: dom = md.parseString(xml_string)
pretty_xml = dom.toprettyxml()
# remove the weird newline issue:
pretty_xml = os.linesep.join([s for s in pretty_xml.splitlines()
if s.strip()])
输出结果与上面相同,但代码更多。
bs4.FeatureNotFound: 找不到具有所请求功能的树构建器:xml。您需要安装解析器库吗?
- hadooppython3 -m pip install --user lxml
。 - reynoldsnlp这是我(hacky?)解决丑陋文本节点问题的方法。
uglyXml = doc.toprettyxml(indent=' ')
text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)
prettyXml = text_re.sub('>\g<1></', uglyXml)
print prettyXml
以上代码将产生:
<?xml version="1.0" ?>
<issues>
<issue>
<id>1</id>
<title>Add Visual Studio 2005 and 2008 solution files</title>
<details>We need Visual Studio 2005/2008 project files for Windows.</details>
</issue>
</issues>
不要这样做:
<?xml version="1.0" ?>
<issues>
<issue>
<id>
1
</id>
<title>
Add Visual Studio 2005 and 2008 solution files
</title>
<details>
We need Visual Studio 2005/2008 project files for Windows.
</details>
</issue>
</issues>
免责声明:可能存在一些限制。
re.compile
在sub
操作之前(我使用了两次re.findall()
,zip
和一个带有str.replace()
的for
循环...) - heltonbikerdoc
是一个 xml.dom.minidom.Document
对象)请返回翻译后的文本。 - cowlinator从Python 3.9版本开始,ElementTree提供了一个indent()
函数来美化XML树。
请参阅https://docs.python.org/zh-cn/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.indent。
使用示例:
import xml.etree.ElementTree as ET
element = ET.XML("<html><body>text</body></html>")
ET.indent(element)
print(ET.tostring(element, encoding='unicode'))
好处是它不需要任何额外的库。欲了解更多信息,请查看https://bugs.python.org/issue14465和https://github.com/python/cpython/pull/15200
正如其他人指出的那样,lxml内置了一个漂亮打印机。
但要注意,默认情况下,它会将CDATA节更改为普通文本,这可能会产生不良影响。
以下是一个Python函数,可以保留输入文件并仅更改缩进(请注意strip_cdata=False
)。此外,它还确保输出使用UTF-8编码而不是默认的ASCII编码(请注意encoding='utf-8'
):
from lxml import etree
def prettyPrintXml(xmlFilePathToPrettyPrint):
assert xmlFilePathToPrettyPrint is not None
parser = etree.XMLParser(resolve_entities=False, strip_cdata=False)
document = etree.parse(xmlFilePathToPrettyPrint, parser)
document.write(xmlFilePathToPrettyPrint, pretty_print=True, encoding='utf-8')
使用示例:
prettyPrintXml('some_folder/some_file.xml')
xmllint
,可以生成一个子进程并使用它。xmllint --format <file>
将输入的XML文件格式化为标准输出。def pretty_print_xml(xml):
proc = subprocess.Popen(
['xmllint', '--format', '/dev/stdin'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
(output, error_output) = proc.communicate(xml);
return output
print(pretty_print_xml(data))
def indent(elem, level=0, more_sibs=False):
i = "\n"
if level:
i += (level-1) * ' '
num_kids = len(elem)
if num_kids:
if not elem.text or not elem.text.strip():
elem.text = i + " "
if level:
elem.text += ' '
count = 0
for kid in elem:
indent(kid, level+1, count < num_kids - 1)
count += 1
if not elem.tail or not elem.tail.strip():
elem.tail = i
if more_sibs:
elem.tail += ' '
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
if more_sibs:
elem.tail += ' '
如果您正在使用DOM实现,每个实现都有其自己的内置漂亮打印形式:
# minidom
#
document.toprettyxml()
# 4DOM
#
xml.dom.ext.PrettyPrint(document, stream)
# pxdom (or other DOM Level 3 LS-compliant imp)
#
serializer.domConfig.setParameter('format-pretty-print', True)
serializer.writeToString(document)
如果你正在使用没有自己的漂亮打印程序或这些漂亮打印程序不完全按照你想要的方式进行操作的其他内容,那么你可能需要编写或子类化自己的序列化器。