[英]Python ElementTree
我有一個具有以下格式的XML文件:
<dir name="A">
<dir name="B">
<file name="foo.txt"/>
</dir>
<dir name="C">
<dir name="D">
<file name="bar.txt"/>
</dir>
</dir>
</dir>
<dir name="E">
<file name="bat.txt"/>
<file name="cat.txt"/>
</dir>
<dir name="F">
<dir name="G">
<file name="dog.txt"/>
<file name="rabbit.txt"/>
</dir>
</dir>
我想使用python ElementTree模塊來刪除其中包含元素的任何元素。 也就是說,我想獲取XML文件的內部元素(其中不包含其他元素的元素)及其所有子元素。 我希望將任何此類元素設置為外部級別。 例如,對於上述XML文件,相應的輸出文件將是:
<dir name="B">
<file name="foo.txt"/>
</dir>
<dir name="D">
<file name="bar.txt"/>
</dir>
<dir name="E">
<file name="bat.txt"/>
<file name="cat.txt"/>
</dir>
<dir name="G">
<file name="dog.txt"/>
<file name="rabbit.txt"/>
</dir>
我該如何實現?
注意使用iterparse時元素的訪問順序 -這是深度優先的搜索:
import xml.etree.ElementTree as ET
with open('data', 'rb') as f:
context = ET.iterparse(f, events=('start', 'end'))
for event, elem in context:
if elem.tag == 'dir':
name = elem.get('name')
print(event, name)
產量
('start', 'A')
('start', 'B') <-- ('start', 'B') is follow immediately by ('end', 'B')
('end', 'B') <--
('start', 'C')
('start', 'D') <-- start is follow immediately by end
('end', 'D')
('end', 'C')
('end', 'A')
('start', 'E') <-- start is follow immediately by end
('end', 'E')
('start', 'F')
('start', 'G') <-- start is follow immediately by end
('end', 'G')
('end', 'F')
啊,您要查找的元素(嵌套最深的dir
元素)是iterparse首先訪問的元素,其中包含start
事件,然后立即具有end
事件(至少當我們僅查看dir
Elements時)。
因此,使用這個想法,我們可以將這些元素收集到新的root
元素中以獲得所需的XML:
root = ET.Element('root')
previous_name = None
with open('data', 'rb') as f:
context = ET.iterparse(f, events=('start', 'end'))
for event, elem in context:
if elem.tag == 'dir':
name = elem.get('name')
if event == 'start':
previous_name = name
elif previous_name == name:
root.append(elem)
print(ET.tostring(root))
產量
<root><dir name="B">
<file name="foo.txt" />
</dir>
<dir name="D">
<file name="bar.txt" />
</dir>
<dir name="E">
<file name="bat.txt" />
<file name="cat.txt" />
</dir>
<dir name="G">
<file name="dog.txt" />
<file name="rabbit.txt" />
</dir>
</root>
請注意,上面的iterparse代碼在被iterparse訪問后不會清除任何元素。 如果您的XML很大,則在不清除任何元素的情況下使用iterparse可能會占用過多的內存。 在那種情況下,為了性能和更好的內存管理,我將使用lxml和fast_iter 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.