#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 всегда был для меня проблемой.