Как разбирать этот огромный XML-файл с вложенными элементами, используя LXML эффективным способом?

Я попытался распределять этот огромный XML-документ с использованием XML MiniDom . Пока он работал нормально в файле пример, он выдохнул систему при попытке обрабатывать реальный файл ( Около 400 МБ).

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

Это правильный подход? Как связать инвентаризацию и идентификаторы издателя в каждую книгу? Вот как я планирую связать 2 столы в конце концов.

Любая обратная связь очень ценится.

Book.xml


    
        BookData
        All
        2010-05-02
        1.1
    

    
        
            
                
                    
                        Microsoft Press
                        Tech
                        7462
                    
                
            
            
                                    
                        2009-01-30
                    
                    
                        
                            Code Complete 2
                            Steve McConnell
                            960
                            0735619670
                        
                        
                            Application Architecture Guide 2
                            Microsoft Team
                            496
                            073562710X
                        
                    
                
            
        
        
            
                
                    
                        O'Reilly Media
                        Tech
                        7484
                    
                
            
            
                                    
                        2009-03-30
                    
                    
                        
                            Head First Design Patterns
                            Kathy Sierra
                            688
                            0596007124
                        
                    
                
            
        
    

Код Python:

import sys
import os
#import MySQLdb
from lxml import etree

CATEGORIES = set(['BookHeader', 'Inventory', 'PublisherClass', 'PublisherDetails', 'BookDetail'])
SKIP_CATEGORIES = set(['BookHeader'])
DATA_ITEMS = ["Name", "Type", "ID", "BookName", "Author", "Pages", "ISBN"]

def clear_element(element):
    element.clear()
    while element.getprevious() is not None:
        del element.getparent()[0]

def extract_book_elements(context):
    for event, element in context:
         if element.tag in CATEGORIES:
               yield element
               clear_element(element)                 

def fast_iter2(context):
    for bookCounter, element in enumerate(extract_book_elements(context)):
            books = [book.text for book in element.findall("BookDetail")]
            bookdetail = {
                'element' : element.tag,
                'ID' : element.get('ID')
            }
            for data_item in DATA_ITEMS:
                data = element.find(data_item)
                if data is not None:
                    bookdetail[data_item] = data

            if bookdetail['element'] not in SKIP_CATEGORIES:
                #populate_database(bookdetail, books, cursor)
                print bookdetail, books

            print "========>", bookCounter , "<======="

def main():
        #cursor = connectToDatabase()
        #cursor.execute("""SET NAMES utf8""")

        context = etree.iterparse("book.xml", events=("start", "end"))
        #fast_iter(context, cursor)
        fast_iter2(context)

        #cursor.close()


if __name__ == '__main__':
    main()            

Вывод Python:

$ python lxmletree_book.py 
========> 0 <=======
========> 1 <=======
{'ID': '12', 'element': 'Inventory'} []
========> 2 <=======
{'ID': '34', 'element': 'PublisherClass'} []
========> 3 <=======
{'Name': , 'Type': , 'ID': , 'element': 'PublisherDetails'} []
========> 4 <=======
{'ID': None, 'element': 'PublisherDetails'} []
========> 5 <=======
{'ID': None, 'element': 'PublisherClass'} []
========> 6 <=======
{'ISBN': , 'Name': , 'Author': , 'ID': '67', 'element': 'BookDetail', 'Pages': } []
========> 7 <=======
{'ID': None, 'element': 'BookDetail'} []
========> 8 <=======
{'ISBN': , 'Name': , 'Author': , 'ID': '78', 'element': 'BookDetail', 'Pages': } []
========> 9 <=======
{'ID': None, 'element': 'BookDetail'} []
========> 10 <=======
{'ID': None, 'element': 'Inventory'} []
========> 11 <=======
{'ID': '64', 'element': 'Inventory'} []
========> 12 <=======
{'ID': '154', 'element': 'PublisherClass'} []
========> 13 <=======
{'Name': , 'Type': , 'ID': , 'element': 'PublisherDetails'} []
========> 14 <=======
{'ID': None, 'element': 'PublisherDetails'} []
========> 15 <=======
{'ID': None, 'element': 'PublisherClass'} []
========> 16 <=======
{'ISBN': , 'Name': , 'Author': , 'ID': '98', 'element': 'BookDetail', 'Pages': } []
========> 17 <=======
{'ID': None, 'element': 'BookDetail'} []
========> 18 <=======
{'ID': None, 'element': 'Inventory'} []
========> 19 <=======

Желаемый вывод (в итоге хранится в MySQL - пока список в Python):

Publishers
InventoryID PublisherClassID Name            Type ID
12          34               Microsoft Press Tech 7462
64          154              O'Reilly Media  Tech 7484

Books
PublisherID BookDetailID Name                              Author           Pages ISBN
7462        67           Code Complete 2                   Steve McConnell  960   0735619670
7462        78           Application Architecture Guide 2  Microsoft Team   496   073562710X
7484        98           Head First Design Patterns        Kathy Sierra     688   0596007124

8
задан Community 23 May 2017 в 12:32
поделиться