序列化为字符串时,如何防止 lxml 自动关闭空元素?

Pet*_*ris 5 python lxml

我正在解析一个巨大的 xml 文件,其中包含许多空元素,例如

<MemoryEnv></MemoryEnv>
Run Code Online (Sandbox Code Playgroud)

序列化时

etree.tostring(root_element, pretty_print=True)
Run Code Online (Sandbox Code Playgroud)

输出元素折叠为

<MemoryEnv/>
Run Code Online (Sandbox Code Playgroud)

有什么办法可以防止这种情况吗?在etree.tostring()不提供这样的设施。

有没有办法干扰 lxml 的tostring()序列化程序?

顺便说一句,该html模块不起作用。它不是为 XML 设计的,也不会以原始形式创建空元素。

问题是,尽管空元素的折叠和未折叠形式是等效的,但解析此文件的程序无法处理折叠的空元素。

mzj*_*zjn 7

这是一种方法。确保text所有空元素的值都不是None

例子:

from lxml import etree

XML = """
<root>
  <MemoryEnv></MemoryEnv>
  <AlsoEmpty></AlsoEmpty>
  <foo>bar</foo>
</root>"""

doc = etree.fromstring(XML)

for elem in doc.iter():
    if elem.text == None:
        elem.text = ''

print etree.tostring(doc)
Run Code Online (Sandbox Code Playgroud)

输出:

from lxml import etree

XML = """
<root>
  <MemoryEnv></MemoryEnv>
  <AlsoEmpty></AlsoEmpty>
  <foo>bar</foo>
</root>"""

doc = etree.fromstring(XML)

for elem in doc.iter():
    if elem.text == None:
        elem.text = ''

print etree.tostring(doc)
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用该write_c14n()方法将规范的 XML(不使用特殊的空元素语法)写入文件。

from lxml import etree

XML = """
<root>
  <MemoryEnv></MemoryEnv>
  <AlsoEmpty></AlsoEmpty>
  <foo>bar</foo>
</root>"""

doc = etree.fromstring(XML)

doc.getroottree().write_c14n("out.xml")
Run Code Online (Sandbox Code Playgroud)

  • 我认为“如何防止 lxml 在序列化为字符串时自动关闭空元素?” 问题已得到解答。我知道这不是您想要的,但是问题中没有明确解释有关漂亮打印和进行差异的能力的要求。 (2认同)

Pet*_*ris 5

使用 XML 方法 (c14n) 进行打印并且它与 lxml 一起使用,它不会折叠空元素。

>>> from lxml import etree
>>> s = "<MemoryEnv></MemoryEnv>"
>>> root_element = etree.XML(s)
>>> etree.tostring(root_element, method="c14n")
b'<MemoryEnv></MemoryEnv>'
Run Code Online (Sandbox Code Playgroud)