xml:从iterparse元素获取父属性

问题描述 投票:2回答:1

我有一个大型的XML文件,其条目如

<data num_entries="1000000000">
   <item value="3.1324213213"></item>
   <item value="6.2432343213"></item>
   <!-- ... -->
</data>

(实际上,有多个data条目,它们在XML树中更深入,但让我们保持简单。)

我想用Python读取这个文件并将所有items放入一个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()

不幸的是,iterparse只有在所有items迭代完毕后才能进入父元素。

如何使用iterparse()访问父属性?

python xml numpy xml-parsing
1个回答
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()
© www.soinside.com 2019 - 2024. All rights reserved.