Как мне сохранить дерево элементов в список на основе атрибута в дочернем теге с помощью модуля LXML Python?

#python #xml #parsing #xpath #lxml

#python #xml #синтаксический анализ #xpath #lxml

Вопрос:

У меня есть XML-документ, который я должен проанализировать. Я использую python 3.8 и модуль lxml.

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

Вот мой пример XML:

 '''
<root>
    <Title ref="111111">
        <Events>
            <Event type="change"/>
        </Events>
        <tag1>John</tag1>
        <tag2>A.</tag2>
        <tag3>Smith</tag3>
    </Title>
        <Title ref="222222">
        <Events>
            <Event type="cancel"/>
        </Events>
        <tag1>Bob</tag1>
        <tag2>B.</tag2>
        <tag3>Hope</tag3>
    </Title>
        <Title ref="333333">
        <Events>
            <Event type="change"/>
        </Events>
        <tag1>Julie</tag1>
        <tag2>A.</tag2>
        <tag3>Moore</tag3>
    </Title>
        <Title ref="444444">
        <Events>
            <Event type="cancel"/>
        </Events>
        <tag1>First</tag1>
        <tag2>M</tag2>
        <tag3>Last</tag3>
    </Title>
</root>
'''
  

Я пытался использовать функцию findall(), но, похоже, она сохраняет только тег «Событие», а не тег «Заголовок» и все его дочерние элементы. Я получаю те же результаты и при использовании xpath.

Ответ №1:

Если txt ваш XML-фрагмент из вопроса, то вы можете сделать это, чтобы извлечь <Title> теги, которые содержат <Event type="change"> :

 from lxml import etree, html

root = etree.fromstring(txt)

for title in root.xpath('.//Title[.//Event[@type="change"]]'):
    print(html.tostring(title).decode('utf-8'))
    print('-' * 80)
  

С принтами:

 <Title ref="111111">
        <Events>
            <Event type="change"></Event>
        </Events>
        <tag1>John</tag1>
        <tag2>A.</tag2>
        <tag3>Smith</tag3>
    </Title>
        
--------------------------------------------------------------------------------
<Title ref="333333">
        <Events>
            <Event type="change"></Event>
        </Events>
        <tag1>Julie</tag1>
        <tag2>A.</tag2>
        <tag3>Moore</tag3>
    </Title>
        
--------------------------------------------------------------------------------
  

Комментарии:

1. Это сработало! Спасибо, Андрей, за ваш простой и быстрый ответ. Xpath всегда был для меня проблемой.