Почему добавление 3 элементов приводит к тому, что findall не работает?

#python #xml #elementtree

#python #xml #elementtree

Вопрос:

Для анализа информации с этого URL: http://py4e-data.dr-chuck.net/comments_42.xml

     url = "http://py4e-data.dr-chuck.net/comments_42.xml"
    fhandle = urllib.request.urlopen(url, context=ctx)
    string_data = fhandle.read()
    xml = ET.fromstring(string_data)
 

Почему

     lst = xml.findall("./commentinfo/comments/comment")
 

Ничего не помещать в lst, пока

     lst = xml.findall("comments/comment")
 

создает список элементов.

Спасибо!

Ответ №1:

Element.findall использует подмножество спецификации XPATH (см. XPATH support ) на основе элемента, на который вы ссылаетесь. Когда вы загружали документ, вы ссылались на корневой элемент <commentinfo> . XPATH comments/comment выбирает все дочерние элементы этого элемента с именем «комментарии», а затем выбирает все их дочерние элементы с именем «комментарий».

./comments/comment идентично comments/comment . «.» является текущим узлом ( <commentinfo> ), а следующий «/ comments» выбирает его дочерние узлы, как указано выше.

./commentinfo/comments/comment то же commentinfo/comments/comment самое, что и . Легко увидеть проблему. Поскольку вы уже находитесь на <commentinfo> узле, нет никаких дочерних элементов, также называемых «commentinfo». Некоторые процессоры XPATH позволяют ссылаться на корень дерева, как в //commentinfo/comments/comment , но ElementTree этого не делает.

Ответ №2:

'.' в XPath здесь уже имеется в виду элемент верхнего уровня <commentinfo> . Итак, ваш path ищет <commentinfo> дочерний элемент этого, которого не существует.

Вы можете убедиться в этом, сопоставив пример из документации с соответствующим XML. Обратите внимание, что ни один из примеров XPath не упоминается data .

Вы хотите просто './comments/comment' .