web-dev-qa-db-fra.com

Python: accéder aux enfants imbriqués dans un fichier xml analysé avec ElementTree

Je suis nouveau dans l'analyse XML. Ce fichier xml a l'arborescence suivante:

FHRSEstablishment
 |--> Header
 |    |--> ...
 |--> EstablishmentCollection
 |    |--> EstablishmentDetail
 |    |    |-->...
 |    |--> Scores
 |    |    |-->...
 |--> EstablishmentCollection
 |    |--> EstablishmentDetail
 |    |    |-->...
 |    |--> Scores
 |    |    |-->...

mais quand j'y accède avec ElementTree et cherche les balises et les attributs child,

import xml.etree.ElementTree as ET
import urllib2
tree = ET.parse(
   file=urllib2.urlopen('http://ratings.food.gov.uk/OpenDataFiles/FHRS408en-GB.xml' % i))
root = tree.getroot()
for child in root:
   print child.tag, child.attrib

Je reçois seulement:

Header {}
EstablishmentCollection {}

ce que je suppose signifie que leurs attributs sont vides. Pourquoi en est-il ainsi et comment puis-je accéder aux enfants imbriqués dans EstablishmentDetail et Scores?

[~ # ~] modifier [~ # ~]

Grâce aux réponses ci-dessous, je peux accéder à l'arborescence, mais si je veux récupérer des valeurs telles que celles de Scores, cela échoue:

for node in root.find('.//EstablishmentDetail/Scores'):
    rating = node.attrib.get('Hygiene')
    print rating 

et produit

None
None
None

Pourquoi donc?

11
FaCoffee

Vous devez iter () sur votre racine.

c'est-à-dire que root.iter() ferait l'affaire!

import xml.etree.ElementTree as ET
import urllib2
tree =ET.parse(urllib2.urlopen('http://ratings.food.gov.uk/OpenDataFiles/FHRS408en-GB.xml'))
root = tree.getroot()
for child in root.iter():
   print child.tag, child.attrib

Sortie:

FHRSEstablishment {}
Header {}
ExtractDate {}
ItemCount {}
ReturnCode {}
EstablishmentCollection {}
EstablishmentDetail {}
FHRSID {}
LocalAuthorityBusinessID {}
...
  • Pour obtenir toutes les balises à l'intérieur de EstablishmentDetail, vous devez trouver cette balise, puis parcourir ses enfants!

C'est,

for child in root.find('.//EstablishmentDetail'):
    print child.tag, child.attrib

Sortie:

FHRSID {}
LocalAuthorityBusinessID {}
BusinessName {}
BusinessType {}
BusinessTypeID {}
RatingValue {}
RatingKey {}
RatingDate {}
LocalAuthorityCode {}
LocalAuthorityName {}
LocalAuthorityWebSite {}
LocalAuthorityEmailAddress {}
Scores {}
SchemeType {}
NewRatingPending {}
Geocode {}
  • Pour obtenir le score de Hygiene comme vous l'avez mentionné dans le commentaire,

Ce que vous avez fait, c'est qu'il obtiendra la première balise Scores et qui aura les balises Hygiene, ConfidenceInManagement, Structural comme enfant lorsque vous appelez for each in root.find('.//Scores'):rating=child.get('Hygiene'). Autrement dit, les trois enfants n'auront évidemment pas l'élément!

Vous devez d'abord - trouver toutes les balises Scores. - trouver Hygiene dans toutes les balises trouvées!

for each in root.findall('.//Scores'):rating = each.find('.//Hygiene'); print '' if rating is None else rating.text;

Production:

5
5
5
0
5
13

J'espère que cela pourrait être utile:

import xml.etree.ElementTree as etree
with open('filename.xml') as tmpfile:
    doc = etree.iterparse(tmpfile, events=("start", "end"))
    doc = iter(doc)
    event, root = doc.next()
    num = 0
    for event, elem in doc:
        print event, elem
1
Andrea