在Python中,美化XML的最佳方法是什么(或者有哪些方法)?
我在使用minidom的pretty print时遇到了一些问题。当我尝试对一个包含给定编码之外字符(例如β)的文档进行pretty-print时,会出现UnicodeError错误,例如我尝试使用doc.toprettyxml(encoding='latin-1')
。以下是我的解决方法:
def toprettyxml(doc, encoding):
"""Return a pretty-printed XML document in a given encoding."""
unistr = doc.toprettyxml().replace(u'<?xml version="1.0" ?>',
u'<?xml version="1.0" encoding="%s"?>' % encoding)
return unistr.encode(encoding, 'xmlcharrefreplace')
我写了一个解决方案,可以遍历现有的ElementTree,并使用文本/尾随来缩进它,就像人们通常期望的那样。
def prettify(element, indent=' '):
queue = [(0, element)] # (level, element)
while queue:
level, element = queue.pop(0)
children = [(level + 1, child) for child in list(element)]
if children:
element.text = '\n' + indent * (level+1) # for child open
if queue:
element.tail = '\n' + indent * queue[0][0] # for sibling open
else:
element.tail = '\n' + indent * (level-1) # for parent close
queue[0:0] = children # prepend so children come before siblings
from yattag import indent
pretty_string = indent(ugly_string)
它不会在文本节点中添加空格或换行符,除非您使用以下方式请求:
indent(mystring, indent_text = True)
您可以指定缩进单位和换行符应该是什么样子。
pretty_xml_string = indent(
ugly_xml_string,
indentation = ' ',
newline = '\r\n'
)
这份文档可以在http://www.yattag.org首页找到。
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)
我在这里找到了如何解决换行问题的方法。
unparse
和pretty=True
,您将获得最佳结果:xmltodict.unparse(
xmltodict.parse(my_xml), full_document=False, pretty=True)
<?xml version="1.0" encoding="UTF-8"?>
,而不是 full_document=False
。from xml.dom.minidom import parseString as string_to_dom
def prettify(string, html=True):
dom = string_to_dom(string)
ugly = dom.toprettyxml(indent=" ")
split = list(filter(lambda x: len(x.strip()), ugly.split('\n')))
if html:
split = split[1:]
pretty = '\n'.join(split)
return pretty
def pretty_print(html):
print(prettify(html))
When used this is what it looks like:
html = """\
<div class="foo" id="bar"><p>'IDK!'</p><br/><div class='baz'><div>
<span>Hi</span></div></div><p id='blarg'>Try for 2</p>
<div class='baz'>Oh No!</div></div>
"""
pretty_print(html)
返回结果如下:
<div class="foo" id="bar">
<p>'IDK!'</p>
<br/>
<div class="baz">
<div>
<span>Hi</span>
</div>
</div>
<p id="blarg">Try for 2</p>
<div class="baz">Oh No!</div>
</div>
indent
。 - undefined请看vkbeautify模块。
这是一个python版本的非常流行的javascript/nodejs插件,名称相同。它可以美化/缩小XML、JSON和CSS文本。输入和输出可以是任意组合的字符串/文件。它非常紧凑,没有任何依赖。
举例:
import vkbeautify as vkb
vkb.xml(text)
vkb.xml(text, 'path/to/dest/file')
vkb.xml('path/to/src/file')
vkb.xml('path/to/src/file', 'path/to/dest/file')
BeautifulSoup
和后端lxml
(解析器)库:user$ pip3 install lxml bs4
处理您的XML文档:
from bs4 import BeautifulSoup
with open('/path/to/file.xml', 'r') as doc:
for line in doc:
print(BeautifulSoup(line, 'lxml-xml').prettify())
lxml
的 XML 解析器 BeautifulSoup(markup, "lxml-xml")
和 BeautifulSoup(markup, "xml")
。 - Umar.Hlxml-xml
),然后在同一天踩了它。我向S/O提交了正式投诉,但他们拒绝调查。不管怎样,我现在已经“去篡改”了我的答案,现在又是正确的了(并像最初一样指定了lxml-xml
)。谢谢。 - NYCeyesimport xml.etree.ElementTree as ET
xmlTree = ET.parse('your XML file')
xmlRoot = xmlTree.getroot()
xmlDoc = ET.tostring(xmlRoot, encoding="unicode")
print(xmlDoc)
<root>
<child>
<subchild>.....</subchild>
</child>
<child>
<subchild>.....</subchild>
</child>
...
...
...
<child>
<subchild>.....</subchild>
</child>
</root>