用Python去除XML节点间的空格

3 投票
3 回答
4312 浏览
提问于 2025-04-15 12:45

有没有简单的方法可以在Python中实现和xsl一样的功能呢?

<xsl:strip-space elements="*"/>

比如说,在下面这个例子中,

for event, elem in ElementTree.iterparse("/tmp/example.xml"):
    if elem.tag == "example":
        print ElementTree.tostring(elem)

当打印出示例节点时,输入文件中示例节点的子节点之间的所有空格和换行符都会被去掉吗?

3 个回答

1

一个优雅的解决方案是可以使用一个迭代器,它只过滤掉那些只有空白的文本节点:

import re

whitespaces = re.compile('\s*$')
def omit_whitespaces(iter):
    for event, elem in iter:
        if whitespaces.match(elem.text): elem.text = ''
        if whitespaces.match(elem.tail): elem.tail = ''
        yield event, elem

def strip_whitespaces(iter):
    for event, elem in iter:
        elem.text = elem.text.strip()
        elem.tail = elem.tail.strip()
        yield event, elem

然后可以这样使用它(可以选择使用 stripomit,这取决于你是否想保留包含非空白字符的文本节点中的空格):

for event, elem in omit_whitespaces(ElementTree.iterparse("/tmp/example.xml")):
    if elem.tag == "example":
        print ElementTree.tostring(elem)

注意,在这种情况下,你只能使用 'end' 事件(否则解析器可能会给你部分数据)。

不过……我对 ElementTree 不是很了解,也没有测试过这段代码。

5

我觉得你需要明确地处理这个子树,以去掉所有的文本和尾部内容:

from xml.etree import ElementTree

for event, elem in ElementTree.iterparse("/tmp/example.xml"):
    if elem.tag == "example":
        subiter = ElementTree.ElementTree(elem).getiterator()
        for x in subiter:
          if x.text: x.text = x.text.strip()
          if x.tail: x.tail = x.tail.strip()
        print ElementTree.tostring(elem)
4

如果你能使用 lxml 这个模块,那事情就简单多了。可以参考 lxml 的教程

>>> parser = etree.XMLParser(remove_blank_text=True) # lxml.etree only!
>>> root = etree.XML("<root>  <a/>   <b>  </b>     </root>", parser)
>>> etree.tostring(root)
b'<root><a/><b>  </b></root>'

撰写回答