python lxml и метод iterparse

Скажем, у меня есть этот образец XML.

<result>
    <field k='field1'>
        <value h='1'><text>text_value1</text></value>
    </field>
    <field k='field2'>
        <value><text>text_value2</text></value>
    </field>
    <field k='field3'>
        <value><text>some_text</text></value>
    </field>
</result>

Используя python lxml, как я могу получить значение каждого поля для каждого набора результатов? Итак, в основном, я хочу перебирать все наборы результатов, затем перебирать каждое поле в этом наборе результатов и печатать текстовые данные.

Это то, что у меня есть до сих пор:

context = etree.iterparse(contentBuffer, tag='result')
for action, elem in context:
    print elem.tag, elem.data

Любая помощь будет принята с благодарностью.

EDIT Вот код, который я придумал. Кажется немного неуклюжим необходимость дважды вызывать getparent() для чтения атрибута соответствующего текстового значения. Есть лучший способ сделать это?

for action, elem in context:
    list = elem.xpath('//text')
    print "result set:"
    for item in list:
        field = item.getparent().getparent().attrib['k']
        value = item.text
        print "\t%s = %s"%(field, value)

person nnachefski    schedule 31.03.2011    source источник
comment
что вы ожидаете от рабочего скрипта?   -  person SingleNegationElimination    schedule 31.03.2011
comment
я хотел бы напечатать имя поля (в атрибуте) = значение (текст). Я бы хотел, чтобы поля были сгруппированы с другими полями в этом наборе результатов.   -  person nnachefski    schedule 31.03.2011


Ответы (2)


Как насчет:

import io
import lxml.etree as ET

content='''\
<result>
    <field k='field1'>
        <value h='1'><text>text_value1</text></value>
    </field>
    <field k='field2'>
        <value><text>text_value2</text></value>
    </field>
    <field k='field3'>
        <value><text>some_text</text></value>
    </field>
</result>'''

contentBuffer=io.BytesIO(content)
context = ET.iterparse(contentBuffer,tag='result')
for action, elem in context:
    fields=elem.xpath('field/@k')
    values=elem.xpath('field/value/text/text()')
    for field,value in zip(fields,values):
        print('\t{f} = {v}'.format(f=field,v=value))

что дает

field1 = text_value1
field2 = text_value2
field3 = some_text
person unutbu    schedule 31.03.2011

Я бы предложил использовать запрос XPath. Что-то вдоль r = tree.xpath('//text') должно быть достаточно для ваших нужд.

person jayeff    schedule 31.03.2011