xml:从iterparse元素获取父属性

时间:2017-12-20 13:06:59

标签: python xml numpy xml-parsing

我有一个包含

等条目的大型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()访问父属性?

1 个答案:

答案 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()