Разбор XML с использованием BeautifulSoup или minidom

У меня есть XML что-то вроде этого

#filename sample.xml
<tag>
<tag1>
<tag2 property="something"/>
<tag2 property="something1"/>
<tag2 property="something2">value</tag2>
<tag2 property="something3">
<tag3>
<tag4 data="data1"/>
<tag4 data="data2"/>
</tag3>
</tag2>
</tag1>
</tag>

Я хочу извлечь 'data1' а также 'data2', Я пытаюсь что-то вроде этого:

f=open('sample.xml')
fdata=f.read()
xmldata=BeautifulSoup(fadata)
print (xmldata.tag.tag1.tag2.tag3.tag4["data"])

Но это выдает ошибку:

AttributeError: 'NoneType' object has no attribute 'tag4'

2 ответа

print функция не работает из-за множественного tag2s. Решение было бы получить все теги с помощью .findAll('tag2'),

Вот рабочий пример:

#! /usr/bin/python

from bs4 import BeautifulSoup
f=open('sample.xml')
fdata=f.read()
xmldata=BeautifulSoup(fdata)

alltags2 = xmldata.tag.tag1.findAll('tag2')

for tag2 in alltags2:
    alltags3 = tag2.findAll('tag3')
    for tag3 in alltags3:
        alltags4 = tag3.findAll('tag4')
        for tag4 in alltags4:
            print "The data I got was :\"%s\"" % (tag4["data"])

С уважением,

Одним из возможных способов является использование select() метод, передающий оператор селектора CSS в качестве параметра. Например, если вы действительно хотите строго выбрать <tag4> имея такую ​​иерархию предков:

.....
xmldata=BeautifulSoup(fadata)
for tag4 in xmldata.select("tag > tag1 > tag2 > tag3 > tag4"):
    print tag4["data"]

Выше будет напечатано следующее:

data1
data2

Или если вам нужно только все <tag4> элементы, где бы они ни находились в XML, вы можете просто использовать xmldata.select("tag4"),

Другие вопросы по тегам