我有一个包含
等条目的大型XML文件<data num_entries="1000000000">
<item value="3.1324213213"></item>
<item value="6.2432343213"></item>
<!-- ... -->
</data>
(实际上,有多个data
条目,它们在XML树中更深入,但让我们保持简单。)
我想用Python读取这个文件并将所有item
放入一个numpy数组中。该文件太大,ET.parse()
不是一个选项。为了避免内存窒息,我使用iterparse()
与elem.clear()
类似
import xml.etree.cElementTree as ET
items = []
for event, elem in ET.iterparse(filename):
if elem.tag == 'item':
items.append(float(elem.attrib['value']))
elem.clear()
items = numpy.array(items)
这可行,但由于items
被逐位分配,因此速度相当慢。我想使用周围num_entries
块的data
信息来首先分配数组,例如
items = None
k = 0
for event, elem in ET.iterparse(filename):
if elem.tag == 'item':
if items is None:
num_entries = get_num_entries_somehow()
items = numpy.empty(num_entries)
items[k] = float(elem.attrib['value'])
k += 1
elem.clear()
不幸的是,在{/ em>所有iterparse
被迭代之后,item
只到的父元素。
如何使用iterparse()
访问父属性?
答案 0 :(得分:3)
您可以通过以下方式从xml的根目录中获取num_entries
:
tree = ET.ElementTree(file=filename)
root = tree.getroot()
print(root.attrib.get('num_entries'))
^上面的方法会立即解析所有树,这是不行的。
如何启用start
事件?
for event, elem in ET.iterparse(filename, events=('start', 'end')):
if elem.tag == 'data' and event == 'start':
print(elem.attrib['num_entries'])
if elem.tag == 'item' and event == 'start':
items.append(float(elem.attrib['value']))
elem.clear()