我有以下代码。
from xml.dom.minidom import Document
doc = Document()
root = doc.createElement('root')
doc.appendChild(root)
main = doc.createElement('Text')
root.appendChild(main)
text = doc.createTextNode('Some text here')
main.appendChild(text)
print doc.toprettyxml(indent='\t')
结果是:
<?xml version="1.0" ?>
<root>
<Text>
Some text here
</Text>
</root>
这一切都很好,但是如果我希望输出看起来像这样呢?
<?xml version="1.0" ?>
<root>
<Text>Some text here</Text>
</root>
这可以轻松完成吗?
... Orjanp
答案 0 :(得分:7)
这可以轻松完成吗?
这取决于您想要的确切规则,但通常不会,您无法控制漂亮的打印。如果你想要一种特定的格式,你通常需要自己编写助行器。
pxdom中的DOM Level 3 LS参数格式 - 漂亮打印非常接近您的示例。它的规则是,如果一个元素只包含一个TextNode,则不会添加额外的空格。然而,它(当前)使用两个空格来缩进而不是四个。
>>> doc= pxdom.parseString('<a><b>c</b></a>')
>>> doc.domConfig.setParameter('format-pretty-print', True)
>>> print doc.pxdomContent
<?xml version="1.0" encoding="utf-16"?>
<a>
<b>c</b>
</a>
(调整您正在进行的任何类型序列化的编码和输出格式。)
如果这是你想要的规则,并且你可以逃脱它,你也可能能够修补minidom的Element.writexml,例如:
>>> from xml.dom import minidom
>>> def newwritexml(self, writer, indent= '', addindent= '', newl= ''):
... if len(self.childNodes)==1 and self.firstChild.nodeType==3:
... writer.write(indent)
... self.oldwritexml(writer) # cancel extra whitespace
... writer.write(newl)
... else:
... self.oldwritexml(writer, indent, addindent, newl)
...
>>> minidom.Element.oldwritexml= minidom.Element.writexml
>>> minidom.Element.writexml= newwritexml
关于猴子修补的不良情况的所有常见警告都适用。
答案 1 :(得分:2)
我一直在寻找完全相同的东西,我发现了这篇文章。 (xml.dom.minidom中提供的缩进打破了我用来操作XML的另一个工具,我需要它缩进)我尝试了一个稍微复杂的例子的接受解决方案,这就是结果:
In [1]: import pxdom
In [2]: xml = '<a><b>fda</b><c><b>fdsa</b></c></a>'
In [3]: doc = pxdom.parseString(xml)
In [4]: doc.domConfig.setParameter('format-pretty-print', True)
In [5]: print doc.pxdomContent
<?xml version="1.0" encoding="utf-16"?>
<a>
<b>fda</b><c>
<b>fdsa</b>
</c>
</a>
漂亮的打印XML格式不正确,我对猴子修补不太满意(即我几乎不知道它意味着什么,并且理解它很糟糕),所以我寻找另一个解决方案。
我正在将输出写入文件,因此我可以将xmlindent程序用于Ubuntu($ sudo aptitude install xmlindent)。所以我只是将未格式化的文件写入文件,然后在python程序中调用xmlindent:
from subprocess import Popen, PIPE
Popen(["xmlindent", "-i", "2", "-w", "-f", "-nbe", file_name],
stderr=PIPE,
stdout=PIPE).communicate()
-w开关导致文件被覆盖,但是令人烦恼的是你可能想要删除的“myfile.xml~”。其他开关是为了获得正确的格式(对我而言)。
P.S。 xmlindent是一个流格式化程序,即您可以按如下方式使用它:
cat myfile.xml | xmlindent > myfile_indented.xml
因此,如果需要,您可以在python脚本中使用它而无需写入文件。
答案 2 :(得分:1)
这可以使用toxml()来完成,使用正则表达式来整理。
>>> from xml.dom.minidom import Document
>>> import re
>>> doc = Document()
>>> root = doc.createElement('root')
>>> _ = doc.appendChild(root)
>>> main = doc.createElement('Text')
>>> _ = root.appendChild(main)
>>> text = doc.createTextNode('Some text here')
>>> _ = main.appendChild(text)
>>> out = doc.toxml()
>>> niceOut = re.sub(r'><', r'>\n<', re.sub(r'(<\/.*?>)', r'\1\n', out))
>>> print niceOut
<?xml version="1.0" ?>
<root>
<Text>Some text here</Text>
</root>
答案 3 :(得分:0)
pyxml包通过使用xml.dom.ext.PrettyPrint()函数为此提供了一个简单的解决方案。它还可以打印到文件描述符。
但不再维护pyxml包。
Oerjan Pettersen
答案 4 :(得分:0)
这个解决方案对我有用,没有猴子修补或停止使用minidom:
from xml.dom.ext import PrettyPrint
from StringIO import StringIO
def toprettyxml_fixed (node, encoding='utf-8'):
tmpStream = StringIO()
PrettyPrint(node, stream=tmpStream, encoding=encoding)
return tmpStream.getvalue()
答案 5 :(得分:0)
最简单的方法是使用prettyxml,并删除标签内的\ n和\ t。这样就可以按照示例中的要求保留缩进。
xml_output = doc.toprettyxml()
nojunkintags = re.sub('>(\n|\t)</', '', xml_output)
print nojunkintags