Интерфейс elementtree
, который также предлагает lxml
, поддерживает это - например, со встроенным деревом элементов в Python 2.7:
>>> from xml.etree import ElementTree as et
>>> x='''<div>
... text1
... <div>
... t1
... </div>
... text2
... <div>
... t2
... </div>
... text3
... </div>'''
>>> t=et.fromstring(x)
>>> for el in t.iter():
... print '%s: %r, %r' % (el.tag, el.text, el.tail)
...
div: '\ntext1\n', None
div: '\n t1\n', '\ntext2\n'
div: '\n t2\n', '\ntext3\n'
В зависимости от вашей версии lxml / elementtree вам может потребоваться записать метод итератора .getiterator()
вместо .iter()
.
Если вам нужен один генератор, который будет выдавать теги и тексты по порядку, например:
def elements_and_texts(t):
for el in t.iter():
yield 'tag', el.tag
if el.text is not None:
yield 'text', el.text
if el.tail is not None:
yield 'tail', el.tail
Это в основном удаляет None
s и дает два кортежа с первым элементом 'tag'
, 'text'
или 'tail'
, чтобы помочь вам различить. Я полагаю, что это не ваш идеальный формат, но не должно быть трудно превратить его во что-то более по вашему вкусу; -).