iterparse элементы очищаются, прежде чем я могу захватить данные - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь использовать Python для анализа большого XML-файла (27 ГБ), используя cElementTree и iterparse.Я могу извлечь все теги, но по какой-то причине ни один из элементов текста не извлекается (всегда отображается «Нет»).Я проверил документацию и StackOverflow, но безрезультатно.Я попытался выполнить синтаксический анализ с lxml в качестве последнего средства, и он работает, но я бы предпочел выяснить это на cElementree, если это возможно.Обновление: когда я закомментирую строку elem.clear (), она показывает анализируемые данные, но теперь я пытаюсь выяснить, почему метод clear () стирает данные до того, как они будут напечатаны (в конечном итоге я хочу поместитьданные в отдельную структуру данных, такую ​​как база данных).Я предполагаю, что мне нужно очистить данные, чтобы не максимально использовать память при разборе файла.Это одна из тех ситуаций «все в Python является объектом»?

Используя меньший образец, извлеченный из файла, я все еще получаю ту же ошибку.Файл XML выглядит примерно так (хотя в нем много записей):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><entityList><entity 
xmlns:ns2="urn:hl7-org:v3" xmlns:ns3="urn:axolotl-com:pdo">
<fragmentId>d68e616e-a6bc-4630-b104-3891859a8ce4</fragmentId>
<aggregateId>H1060734453</aggregateId>
<source>b6167864-5f74-40e5-97c5-7e551a3a4a7d</source>
<sourceName>SHM ADT</sourceName>
<sourceOid>2.16.840.1.113883.3.2.2.3.1.21.3</sourceOid>
<sourceAaoid>2.16.840.1.113883.3.62.2</sourceAaoid>
</entity></entityList>

Вот фрагмент неверного кода:

import xml.etree.ElementTree as etree
xml=r'C:\sample.xml'

count = 0

for event, elem in etree.iterparse(xml):
    if event == 'end':
        if elem.tag == 'entity':
            count+=1        
                for child in elem:
                    print (child.tag, child.attrib, child.text)
    elem.clear()
print(count)

Я получаю

fragmentId {} None
aggregateId {} None
source {} None
sourceName {} None
sourceOid {} None
sourceAaoid {} None

Почему elem.clear () стирает текст, даже если кажется, что печать должна произойти первой?Есть предложения?

1 Ответ

0 голосов
/ 04 января 2019

Вот как я бы это сделал, также я не уверен, что вы хотите сделать с данными, поэтому я просто печатаю их, как вы:

import xml.etree.ElementTree as ET

tree = ET.parse(path_to_xml)
root = tree.getroot()

def tree_parser(root):
    for child in root.getchildren():
        if not child.getchildren():
            print(child.tag, child.text)
        else:
            tree_parser(child)

tree_parser(root) 

fragmentId d68e616e-a6bc-4630-b104-3891859a8ce4
aggregateId H1060734453
source b6167864-5f74-40e5-97c5-7e551a3a4a7d
sourceName SHM ADT
sourceOid 2.16.840.1.113883.3.2.2.3.1.21.3
sourceAaoid 2.16.840.1.113883.3.62.2

Согласно вашему комментарию:

def tree_parser(root, seen=set()):
    for child in root.getchildren():
        if not child.getchildren():
            data = (child.tag, child.text)
            seen.add(data)
        else:
            tree_parser(child, seen)
    return seen

for _, element in etree.iterparse(path_to_xml):
    c = tree_parser(element)

print(c)

{('aggregateId', 'H1060734453'),
 ('fragmentId', 'd68e616e-a6bc-4630-b104-3891859a8ce4'),
 ('source', 'b6167864-5f74-40e5-97c5-7e551a3a4a7d'),
 ('sourceAaoid', '2.16.840.1.113883.3.62.2'),
 ('sourceName', 'SHM ADT'),
 ('sourceOid', '2.16.840.1.113883.3.2.2.3.1.21.3')}
...