2017-12-20 17 views
2

에서 부모 속성을 얻을 내가 XML은 : iterparse 요소

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

같은 항목이 큰 XML 파일이 (사실, 여러 data 항목이하고는 XML 트리의 깊은하지만 이제 간단하게 할 수 있습니다.)

이 파일을 파이썬으로 읽고 싶습니다. 모든 item을 numpy 배열에 넣고 싶습니다. 파일이 너무 커서 ET.parse()은 옵션이 아닙니다. 메모리에 질식 방지하기 위해, 나는이 작동하지만 items가 조금씩 할당되기 때문에 상당히 느리다 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) 

등으로 iterparse()을 사용하고 있습니다. 나는 iterparse 모든 item의이 반복 된 된 후 부모 요소에 도달, 즉, 먼저 배열을 할당하는 주변 data 블록의 num_entries 정보를 사용하는

불행하게도
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()으로 상위 속성에 액세스하는 방법은 무엇입니까?

답변

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() 
+0

옵션은 없습니다. 파일이 너무 커서 한 번에 파싱 할 수 없습니다. 나는 OP에서 그것을 분명히했습니다. –

+1

@ NicoSchlömer : 지적 해 주셔서 고맙습니다. 내 대답을 수정하십시오. –

+0

아, 이제 알겠습니다. 'events = ('start', 'end')'가 없으면, 파서는 끝에 구문 분석 만 할 것이고, 그 전후에 엔트리를 방문 할 것이다. 내가 필요한 것. 고맙습니다! –