摘要:以ElementTree元素的形式提供以下片段...
<text:p>Text of the paragraph, <text:span>wrapped text</text:span>
continuing <text:soft-page-break />and more of the text.</text:p>
如何有效地从结构中删除<text:soft-page-break />
元素?
详细信息:我从 OpenDocument 格式(来自Microsoft Word)存储的content.xml
文件中提取了my.odt
个文件。我的目标是将其转换为AsciiDoc格式。这意味着识别重要部分,并丢弃其他部分。
我正在使用xml.etree.ElementTree
将XML文件解析到内存中。由于文档没有良好的内部标记(您知道用户如何使用WYSIWYG工具),因此转换是针对特定文档(书籍)而定制的。
说,我想实现像remove_empty_elements(root, 'text:soft-page-break', namespaces)
这样的功能。我知道可以从父元素中删除子元素的element.remove(subelement)
。以下实现不正确:
def remove_empty_elements(root, tag, namespaces):
lst = []
for parent in root.iterfind('.//' + tag + '/..', namespaces):
e = parent.find('./' + tag, namespaces)
if e.text is None:
lst.append((parent, e))
for parent, e in lst:
parent.remove(e)
这是不正确的,因为and more of the text.
部分属于被删除的元素(如e.tail
),文本将随元素一起删除。
如何将e.tail
文本加入前一个元素的尾部?或者有更好的方法吗?
答案 0 :(得分:1)
以下解决方案仅依赖于xml.etree.ElementTree
的{{3}}。
import xml.etree.ElementTree as ET
sample = '''
<doc xmlns:text="http://example.com/">
<text:p>Text of the paragraph, <text:span>wrapped text</text:span>
continuing <text:soft-page-break />and more of the text.</text:p>
</doc>
'''
class MyTreeBuilder(ET.TreeBuilder):
def start(self, tag, attrib):
if not tag.endswith('soft-page-break'):
return super(MyTreeBuilder, self).start(tag, attrib)
def end(self, tag):
if not tag.endswith('soft-page-break'):
return super(MyTreeBuilder, self).end(tag)
def my_fromstring(data):
parser = ET.XMLParser(target=MyTreeBuilder())
parser.feed(data)
return parser.close()
print ET.tostring(my_fromstring(sample))