Я попытался распределять этот огромный 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