2012-12-29 3 views
2

У меня есть большой XML-файл (около 84MB), который находится в такой форме:Неприятности при разборе с питона очень большой XML-файл

<books> 
    <book>...</book> 
    .... 
    <book>...</book> 
</books> 

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

from xml.dom.minidom import parse, parseString 

fd = "myfile.xml" 
parser = parse(fd) 
## other python code here 

но код кажется сбой в инструкции синтаксического анализа. Почему это происходит и как я могу это решить?

Следует отметить, что файл может содержать греческие, испанские и арабские символы.

Это выход я получил в IPython:

In [2]: fd = "myfile.xml" 

In [3]: parser = parse(fd) 
Killed 

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

+1

Определить «сбой» ... – Thomas

+1

Не могли бы вы предоставить трассировку стека здесь? –

+0

Выполнение python myparser.py оболочка убита. Я забыл сказать, что у меня нет символов ascii ... может это проблема? – user601836

ответ

6

Я бы настоятельно рекомендовал использовать синтаксический анализатор SAX здесь. Я бы не рекомендовал использовать minidom на любом XML-документе размером более нескольких мегабайт; Я видел, что он использовал около 400 Мбайт ОЗУ в XML-документе размером около 10 МБ. Я подозреваю, что проблемы, которые возникают у вас, вызваны minidom, запрашивающим слишком много памяти.

Python поставляется с XML SAX парсером. Чтобы использовать его, сделайте следующее.

from xml.sax.handlers import ContentHandler 
from xml.sax import parse 

class MyContentHandler(ContentHandler): 
    # override various ContentHandler methods as needed... 


handler = MyContentHandler() 
parse("mydata.xml", handler) 

Ваш ContentHandler подкласс переопределяет различные методы ContentHandler (такие как startElement, startElementNS, endElement, endElementNS или characters. Эти обрабатывать события, генерируемые SAX парсер, как он читает ваш XML-документ в.

SAX является более «низкоуровневым» способом обработки XML, чем DOM, в дополнение к вытягиванию соответствующих данных из документа, вашему ContentHandler необходимо будет выполнять работу, отслеживая, какие элементы она находится внутри.Однако, несмотря на то, что, поскольку аналитики SAX не хранят весь документ в памяти, они могут обрабатывать XML-документы потенциально любого размера, в том числе и более крупных.

Я не пробовал другие, используя DOM-парсеры, такие как lxml на XML-документах такого размера, но я подозреваю, что lxml по-прежнему занимает значительное время и использует значительный объем памяти для анализа вашего XML-документа. Это может замедлить ваше развитие, если каждый раз, когда вы запускаете свой код, вам нужно дождаться его чтения в XML-документе на 84 МБ.

Наконец, я не верю, что упоминаемые вами греческие, испанские и арабские символы вызовут проблему.

3

Существует 2 вида анализаторов XML (это относится к любому языку).

  1. DOM parsing (это то, что вы используете). В этом типе весь XML-файл считывается в структуры памяти, а затем осуществляется с помощью методов.

  2. SAX парсинг. Это алгоритм синтаксического анализа, который читает каждую часть XML поэтапно. Этот метод позволит вам лучше выявлять и обрабатывать ошибки.

В целом DOM проще, чем SAX, потому что многие подробные детали обрабатываются его собственными методами.

SAX - это немного более сложная задача, потому что вам нужно программировать методы, которые синтаксический анализ SAX «работает» во время прохождения XML-документа.

7

Попробуйте с lxml, который более прост в использовании.

#!/usr/bin/env python 
from lxml import etree 

with open("myfile.xml") as fp: 
    tree = etree.parse(fp) 
    root = tree.getroot() 

    print root.tag 

    for book in root: 
     print book.text 
Смежные вопросы