【问题标题】:Python xml minidom. generate <text>Some text</text> elementPython xml minidom。生成 <text>一些文本</text> 元素
【发布时间】:2009-02-03 14:59:17
【问题描述】:

我有以下代码。

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...

【问题讨论】:

  • 我也想知道这个,但我对接受的答案不满意,因为要使用它我需要安装 pxdom...
  • 使用当前版本的 xml.dom.minidom,该错误现已修复
  • 这个问题为我节省了很多时间

标签: python xml minidom


【解决方案1】:

这很容易做到吗?

这取决于您想要什么确切的规则,但通常不会,您几乎无法控制漂亮的打印。如果你想要一种特定的格式,你通常必须编写自己的 walker。

pxdom 中的 DOM Level 3 LS 参数 format-pretty-print 与您的示例非常接近。它的规则是,如果一个元素只包含一个 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

所有关于猴子补丁坏处的常见警告都适用。

【讨论】:

  • 谢谢。因为我不会经常手动读取这些文件,而且这不容易做到,我想我就让它保持原样。并将我的注意力集中在更重要的事情上,比如让这个加载/保存到 xml 工作。 Orjanp...
【解决方案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 格式不正确,而且我对猴子补丁不太满意(即我几乎不知道它的含义,并且理解它很糟糕),所以我寻找了另一种解决方案。

我正在将输出写入文件,因此我可以在 Ubuntu 上使用 xmlindent 程序($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 开关会导致文件被覆盖,但令人讨厌的是会留下一个命名的 e.g. “myfile.xml~”你可能想要删除。其他开关可以让格式正确(对我来说)。

附: xmlindent 是一个流格式化程序,即您可以按如下方式使用它:

cat myfile.xml | xmlindent > myfile_indented.xml

因此,如果需要,您可以在 python 脚本中使用它而无需写入文件。

【讨论】:

    【解决方案3】:

    这可以通过 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>
    

    【讨论】:

      【解决方案4】:

      pyxml 包通过使用 xml.dom.ext.PrettyPrint() 函数提供了一个简单的解决方案。它还可以打印到文件描述符。

      但是pyxml包已经不再维护了。

      欧尔扬·彼得森

      【讨论】:

        【解决方案5】:

        此解决方案对我有用,无需猴子修补或停止使用 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

        【讨论】:

        • 是的,这里已经提到了这个解决方案。但如果我没记错的话,这个解决方案需要安装 pyxml。 Pyxml 目前似乎没有维护。所以我想一个不同的解决方案是一个更好的解决方案,比如 lxml。 stackoverflow.com/questions/507405/…
        【解决方案6】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-29
          • 2023-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-07
          • 2012-11-15
          • 1970-01-01
          相关资源
          最近更新 更多