Конкретный путь для поиска элементов XML с использованием мини-диска в Python

Как этот поток, я использую xml.dom.minidom, чтобы сделать некоторые очень простые перемещения XML, только для чтения.

Что меня смущает, так это то, что его getElementsByTagName находит узлы на нескольких уровнях иерархии, без явного указания его точного пути.

XML:

<data>
    <items>
        <item name="item1"></item>
        <item name="item2"></item>
        <item name="item3"></item>
        <item name="item4"></item>
    </items>
    <secondSetOfItems>
        <item name="item5"></item>
        <item name="item6"></item>
        <item name="item7"></item>
        <item name="item8"></item>
    </secondSetOfItems>
</data>

Код Python:

xmldoc = minidom.parse('sampleXML.xml')
items = xmldoc.getElementsByTagName('item') 

for item in items:
    print item.attributes['name'].value

Печать

item1
item2
item3
item4
item5
item6
item7
item8

Меня беспокоит то, что он неявно находит теги с именем item под data->items, а также data->secondSetOfItems.

Как мне сделать это по явному пути и только извлекать элементы в одной из двух категорий? Например. под data->secondSetOfItems:

item5
item6
item7
item8

Ответ 1

Если вы хотите получать элементы из определенной категории, вы можете сделать это, сначала захватив родительский элемент.

Например:

Код

xmldoc = minidom.parse('sampleXML.xml')
#Grab the first occurence of the "secondSetOfItems" element
second_items = xmldoc.getElementsByTagName("secondSetOfItems")[0]
item_list = second_items.getElementsByTagName("item")

for item in item_list:
    print item.attributes['name'].value

Выход

item5
item6
item7
item8

Ответ 2

это объявленное поведение getElementsByTagName

Искать всех потомков (прямых детей, детей детей и т.д.) с определенным именем типа элемента.

кто-то написал "фильтр" на нем, см. этот ответ

мне кажется, что minidom слишком прост, рассмотрим использование lxml xpath:

tree.xpath('//secondSetOfItems/item/@name')

или BeautifulSoup findAll:

data.secondSetOfItems.item.findAll('name')