Итерировать по SAX - PullRequest
       4

Итерировать по SAX

0 голосов
/ 09 сентября 2011

У меня есть такой xml (просто пример):

<xml>
  <page>
    <lol>
    </lol>
    <lel>
    </lel>
  </page>
  <page>
    <lol>
    </lol>
    <lel>
    </lel>
  </page>
  <page>
    <lol>
    </lol>
    <lel>
    </lel>
  </page>
</xml>

Мне нужен способ сделать что-то вроде этого:

#Sax code

for page in something:
  parse(page)

Как я могу сделать это с помощью sax?

XML-файл содержит 30 ГБ данных.

Ответы [ 4 ]

2 голосов
/ 09 сентября 2011

Не используйте SAX, используйте ElementTree вместо:

from xml.etree import cElementTree as ET

for event, elem in ET.iterparse("/path/to/your/file"):
    if elem.tag == 'page':
        # do your processing
        elem.clear()

Важным является вызов elem.clear(), в противном случае вы сохраните все обработанные элементы в памяти и в конечном итоге также будете использовать всю свою оперативную память. Объекты-элементы - это легкие DOM-подобные объекты, поэтому они довольно просты в использовании по сравнению с SAX.

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

1 голос
/ 16 сентября 2012

Самый эффективный и питонный способ сделать это с xml.sax - это использовать метод parser.feed () .

Пример:

parser = xml.sax.make_parser()
parser.setContentHandler(YourContentHandler)

f = open('terribly_large.xml', 'r')
for line in f.xreadlines():
    parser.feed(line)

Это гарантирует, что вы будете постепенно читать файл и разбирать его.

Полученный объем памяти должен быть минимальным.

0 голосов
/ 09 сентября 2011

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

0 голосов
/ 09 сентября 2011

используйте Dom вместо Sax, sax keep fire, когда это происходит, интересует такие вещи, как начальный элемент или текст, но если вы хотите перебрать файл, используйте эту ссылку , которая может вам помочь.

UPDATE:

с 30 ГБ вы должны использовать SAX

...