Python xml minidom。生成<text>一些文本</text>元素

时间:2009-02-03 14:59:17

标签: python xml minidom

我有以下代码。

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

6 个答案:

答案 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()

http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace/#best-solution

答案 5 :(得分:0)

最简单的方法是使用prettyxml,并删除标签内的\ n和\ t。这样就可以按照示例中的要求保留缩进。

xml_output = doc.toprettyxml() nojunkintags = re.sub('>(\n|\t)</', '', xml_output) print nojunkintags