Разбор большого XML-файла с помощью Python lxml и Iterparse - PullRequest
2 голосов
/ 25 августа 2011

Я пытаюсь написать синтаксический анализатор, используя lxml и метод iterparse, чтобы просмотреть очень большой xml-файл, содержащий много элементов.

Мой файл имеет формат:

<item>
  <title>Item 1</title>
  <desc>Description 1</desc>
  <url>
     <item>http://www.url1.com</item>
  </url>
</item>
<item>
  <title>Item 2</title>
  <desc>Description 2</desc>
  <url>
     <item>http://www.url2.com</item>
  </url>
</item>

и пока мое решение:

from lxml import etree

context = etree.iterparse( MYFILE, tag='item' )

for event, elem in context :
      print elem.xpath( 'description/text( )' )
      elem.clear( )
      while elem.getprevious( ) is not None :
            del elem.getparent( )[0]

del context

Когда я запускаю его, я получаю нечто похожее на:

[]
['description1']
[]
['description2']

Пустые наборы объясняются тем, что он также извлекает теги элементов, которые являются дочерними, для тега url, и у них, очевидно, нет поля описания, которое можно извлечь с помощью xpath. Я надеялся разобрать каждый из элементов 1 на 1, а затем обработать дочерние поля по мере необходимости. Я как раз изучаю библиотеку lxml, поэтому мне любопытно, есть ли способ вытащить основные элементы, оставив при этом какие-либо вспомогательные элементы в одиночку?

1 Ответ

4 голосов
/ 25 августа 2011

Весь xml все равно анализируется базовой реализацией.Etree.iterparse - это просто представление в стиле генератора, которое обеспечивает простую фильтрацию по имени тега (см. Строку документации http://lxml.de/api/lxml.etree.iterparse-class.html).. Если вам нужна сложная фильтрация, вы должны сделать это самостоятельно.

Решение: регистрация на стартовое событие также:

iterparse(self, source, events=("start", "end",), tag="item")

и у вас есть бул, чтобы знать, когда вы находитесь в конце «item», когда вы находитесь в конце «item / url / item».

...