Невозможно найти элемент по атрибуту с помощью lxml - PullRequest
0 голосов
/ 28 ноября 2018

Я использую API Европейского космического агентства для запроса (результат можно просмотреть здесь ) для метаданных спутникового изображения дляпарсинг в объекты Python.

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

# loading the response into an ElementTree
tree = etree.fromstring(response.content)
root = tree.getroot()
ns = root.nsmap

# get the first entry element and its summary
e = root.find('entry',ns)
summary = e.find('summary',ns).text

print summary

>> 'Date: 2018-11-28T09:10:56.879Z, Instrument: OLCI, Mode: , Satellite: Sentinel-3, Size: 713.99 MB'

Элемент entry имеет несколько date потомков с различными значениямиattriubute name :

for d in e.findall('date',ns):
    print d.tag, d.attrib

>> {http://www.w3.org/2005/Atom}date {'name': 'creationdate'} {http://www.w3.org/2005/Atom}date {'name': 'beginposition'} {http://www.w3.org/2005/Atom}date {'name': 'endposition'} {http://www.w3.org/2005/Atom}date {'name': 'ingestiondate'}

Я хочу получить элемент даты beginposition с использованием синтаксиса XPath [@attrib='value'], но это простоВозвращает None.Даже простой поиск элемента даты с атрибутом имени ([@attrib]) возвращает None:

dt_begin = e.find('date[@name="beginposition"]',ns) # dt_begin is None
dt_begin = e.find('date[@name]',ns)                 # dt_begin is None

Элемент entry включает в себя другие дочерние элементы, которые демонстрируют такое же поведение, например несколько элементов str с отличающимися атрибутами name .

Кто-нибудь сталкивался с чем-либо подобным или я что-то упустил?Я использую Python 2.7.14 с lxml 4.2.4

1 Ответ

0 голосов
/ 28 ноября 2018

Похоже, что при использовании предиката ([@name="beginposition"]) требуется явный префикс.Вот тестовая программа:

from lxml import etree

print etree.LXML_VERSION

tree = etree.parse("data.xml")  

ns1 = tree.getroot().nsmap
print ns1
print tree.find('entry', ns1)
print tree.find('entry/date', ns1)
print tree.find('entry/date[@name="beginposition"]', ns1)

ns2 = {"atom": 'http://www.w3.org/2005/Atom'}
print tree.find('atom:entry', ns2)
print tree.find('atom:entry/atom:date', ns2)
print tree.find('atom:entry/atom:date[@name="beginposition"]', ns2)

Вывод:

(4, 2, 5, 0)
{None: 'http://www.w3.org/2005/Atom', 'opensearch': 'http://a9.com/-/spec/opensearch/1.1/'}
<Element {http://www.w3.org/2005/Atom}entry at 0x7f8987750b90>
<Element {http://www.w3.org/2005/Atom}date at 0x7f89877503f8>
None
<Element {http://www.w3.org/2005/Atom}entry at 0x7f8987750098>
<Element {http://www.w3.org/2005/Atom}date at 0x7f898774a950>
<Element {http://www.w3.org/2005/Atom}date at 0x7f898774a7a0>
...