Метод .find в элементе lxml будет искать только прямые дочерние элементы этого элемента.так, например, в этом xml:
<root>
<brandName type="http://example.com/codes/bmw#" abbrev="BMW" value="BMW">BMW</brandName>
<maxspeed>
<value>250</value>
<unit type="http://example.com/codes/units#" value="miles per hour" abbrev="mph" />
</maxspeed>
</root>
Вы можете использовать корневой метод Elements .find, чтобы найти элемент фирменного наименования или элемент maxspeed, но поиск не будет проходить внутри этих внутренних элементов.
Таким образом, вы можете, например, сделать что-то вроде этого:
root.find('maxspeed').find('unit') #returns the unit Element
Из этого возвращенного элемента вы можете получить доступ к атрибутам.
Если вы хотите выполнить поиск по всем элементам внутриXML-документ, вы можете использовать метод .iter ().Таким образом, для предыдущего примера вы могли бы сказать:
for element in root.iter(tag='unit'):
print element #This would print all the unit elements in the document.
РЕДАКТИРОВАТЬ: Вот небольшой полнофункциональный пример с использованием предоставленного вами XML:
import lxml.etree
from StringIO import StringIO
def ns_join(element, tag, namespace=None):
'''Joins the namespace and tag together, and
returns the fully qualified name.
@param element - The lxml.etree._Element you're searching
@param tag - The tag you're joining
@param namespace - (optional) The Namespace shortname default is None'''
return '{%s}%s' % (element.nsmap[namespace], tag)
def parse_car(element):
'''Parse a car element, This will return a dictionary containing
brand_name, maxspeed_value, and maxspeed_unit'''
maxspeed = element.find(ns_join(element,'maxspeed'))
return {
'brand_name' : element.findtext(ns_join(element,'brandName')),
'maxspeed_value' : maxspeed.findtext(ns_join(maxspeed,'value')),
'maxspeed_unit' : maxspeed.find(ns_join(maxspeed, 'unit')).attrib['abbrev']
}
#Create the StringIO object to feed to the parser.
XML = StringIO('''
<Reports>
<Car xmlns="http://example.com/vocab/xml/cars#">
<dateStarted>2011-02-05</dateStarted>
<dateSold>2011-02-13</dateSold>
<name type="http://example.com/codes/bmw#" abbrev="X6" value="BMW X6" >BMW X6</name>
<brandName type="http://example.com/codes/bmw#" abbrev="BMW" value="BMW" >BMW</brandName>
<maxspeed>
<value>250</value>
<unit type="http://example.com/codes/units#" value="miles per hour" abbrev="mph" />
</maxspeed>
<route type="http://example.com/codes/routes#" abbrev="HW" value="Highway" >Highway</route>
<power>
<value>180</value>
<unit type="http://example.com/codes/units#" value="powerhorse" abbrev="ph" />
</power>
<frequency type="http://example.com/codes/frequency#" value="daily" >Daily</frequency>
</Car>
</Reports>
''')
#Get the root element object of the xml
car_root_element = lxml.etree.parse(XML).getroot()
# For each 'Car' tag in the root element,
# we want to parse it and save the list as cars
cars = [ parse_car(element)
for element in car_root_element.iter() if element.tag.endswith('Car')]
print cars
Надеюсь, этопомогает.