如何从 ElementTree 中删除 <text:soft-page-break /> 元素?
How to remove the <text:soft-page-break /> element from the ElementTree?
摘要: 具有以下 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 />
元素?
详细信息: 我从 my.odt
文件中提取了 content.xml
文件,以 OpenDocument 格式存储(来自 Microsoft Word)。我的目标是将其转换为 AsciiDoc 格式。意思是认清重要的部分,把其他的部分丢掉。
我正在使用 xml.etree.ElementTree
将 XML 文件解析到内存中。由于文档没有很好的内部标记(您知道用户如何使用所见即所得工具),因此转换是针对特定文档(一本书)量身定制的。
说,我想实现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
文本连接到前一个元素的尾部?或者有什么更好的方法吗?
这里是一个只依赖于xml.etree.ElementTree
的documented API的解决方案。
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))
摘要: 具有以下 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 />
元素?
详细信息: 我从 my.odt
文件中提取了 content.xml
文件,以 OpenDocument 格式存储(来自 Microsoft Word)。我的目标是将其转换为 AsciiDoc 格式。意思是认清重要的部分,把其他的部分丢掉。
我正在使用 xml.etree.ElementTree
将 XML 文件解析到内存中。由于文档没有很好的内部标记(您知道用户如何使用所见即所得工具),因此转换是针对特定文档(一本书)量身定制的。
说,我想实现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
文本连接到前一个元素的尾部?或者有什么更好的方法吗?
这里是一个只依赖于xml.etree.ElementTree
的documented API的解决方案。
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))