Parser un flux XML afin de le valider, extraire des données et l'afficher à l'écran avec une bonne indentation, tout ceci est possible grâce au module xml.dom.minidom.
Exemple avec Python3 et le flux XML suivant:
>>> flux = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><geonames style="MEDIUM"><totalResultsCount>5</totalResultsCount><geoname><toponymName>Republic of Austria</toponymName><name>Austria</name><lat>47.33333</lat><lng>13.33333</lng><geonameId>2782113</geonameId><countryCode>AT</countryCode><countryName>Austria</countryName><fcl>A</fcl><fcode>PCLI</fcode></geoname><geoname><toponymName>Republic of France</toponymName><name>France</name><lat>46</lat><lng>2</lng><geonameId>3017382</geonameId><countryCode>FR</countryCode><countryName>France</countryName><fcl>A</fcl><fcode>PCLI</fcode></geoname><geoname><toponymName>Federal Republic of Germany</toponymName><name>Germany</name><lat>51.5</lat><lng>10.5</lng><geonameId>2921044</geonameId><countryCode>DE</countryCode><countryName>Germany</countryName><fcl>A</fcl><fcode>PCLI</fcode></geoname><geoname><toponymName>Repubblica Italiana</toponymName><name>Italy</name><lat>42.83333</lat><lng>12.83333</lng><geonameId>3175395</geonameId><countryCode>IT</countryCode><countryName>Italy</countryName><fcl>A</fcl><fcode>PCLI</fcode></geoname><geoname><toponymName>Principality of Liechtenstein</toponymName><name>Liechtenstein</name><lat>47.16667</lat><lng>9.53333</lng><geonameId>3042058</geonameId><countryCode>LI</countryCode><countryName>Liechtenstein</countryName><fcl>A</fcl><fcode>PCLI</fcode></geoname></geonames>'
>>> from xml.dom.minidom import parseString
>>> from pprint import pprint
>>> # La commande suivante permet de créer le parseur et de valider le flux XML par la même occasion
>>> parser = parseString(flux)
>>> # La commande suivante permet d'afficher le flux XML correctement indenté
>>> print(parser.toprettyxml())
<?xml version="1.0" ?>
<geonames style="MEDIUM">
<totalResultsCount>5</totalResultsCount>
<geoname>
<toponymName>Republic of Austria</toponymName>
<name>Austria</name>
<lat>47.33333</lat>
<lng>13.33333</lng>
<geonameId>2782113</geonameId>
<countryCode>AT</countryCode>
<countryName>Austria</countryName>
<fcl>A</fcl>
<fcode>PCLI</fcode>
</geoname>
<geoname>
<toponymName>Republic of France</toponymName>
<name>France</name>
<lat>46</lat>
<lng>2</lng>
<geonameId>3017382</geonameId>
<countryCode>FR</countryCode>
<countryName>France</countryName>
<fcl>A</fcl>
<fcode>PCLI</fcode>
</geoname>
<geoname>
<toponymName>Federal Republic of Germany</toponymName>
<name>Germany</name>
<lat>51.5</lat>
<lng>10.5</lng>
<geonameId>2921044</geonameId>
<countryCode>DE</countryCode>
<countryName>Germany</countryName>
<fcl>A</fcl>
<fcode>PCLI</fcode>
</geoname>
<geoname>
<toponymName>Repubblica Italiana</toponymName>
<name>Italy</name>
<lat>42.83333</lat>
<lng>12.83333</lng>
<geonameId>3175395</geonameId>
<countryCode>IT</countryCode>
<countryName>Italy</countryName>
<fcl>A</fcl>
<fcode>PCLI</fcode>
</geoname>
<geoname>
<toponymName>Principality of Liechtenstein</toponymName>
<name>Liechtenstein</name>
<lat>47.16667</lat>
<lng>9.53333</lng>
<geonameId>3042058</geonameId>
<countryCode>LI</countryCode>
<countryName>Liechtenstein</countryName>
<fcl>A</fcl>
<fcode>PCLI</fcode>
</geoname>
</geonames>
>>> # On peut également en profiter pour écrire le contenu dans un fichier et correctement indenté
>>> with open('monFlux.xml', 'w') as f:
f.write(parser.toprettyxml()
)
1494
>>> # Afficher le nombre total d'éléments (correspond à la valeur de la balise totalResultsCount)
>>> print(parser.getElementsByTagName('totalResultsCount')[0].firstChild.data)
5
>>> # La commande suivante permet d'extraire les données d'un tag précis
>>> # et de les sauvegarder dans un dictionnaire
>>> datas = dict()
>>> geonames = parser.getElementsByTagName('geoname')
>>> for geoname in geonames:
toponymName = geoname.getElementsByTagName('toponymName')[0].firstChild.data
name = geoname.getElementsByTagName('name')[0].firstChild.data
lat = geoname.getElementsByTagName('lat')[0].firstChild.data
lng = geoname.getElementsByTagName('lng')[0].firstChild.data
geonameid = geoname.getElementsByTagName('geonameId')[0].firstChild.data
countrycode = geoname.getElementsByTagName('countryCode')[0].firstChild.data
countryname = geoname.getElementsByTagName('countryName')[0].firstChild.data
fcl = geoname.getElementsByTagName('fcl')[0].firstChild.data
fcode = geoname.getElementsByTagName('fcode')[0].firstChild.data
datas[geonameid] = {'toponymName': toponymName, 'name': name, 'lat': lat, 'lng': lng, 'countryCode': countrycode, 'countryName': countryname, 'fcl': fcl, 'fcode': fcode}
>>> pprint(datas)
{'2782113': {'countryCode': 'AT',
'countryName': 'Austria',
'fcl': 'A',
'fcode': 'PCLI',
'lat': '47.33333',
'lng': '13.33333',
'name': 'Austria',
'toponymName': 'Republic of Austria'},
'2921044': {'countryCode': 'DE',
'countryName': 'Germany',
'fcl': 'A',
'fcode': 'PCLI',
'lat': '51.5',
'lng': '10.5',
'name': 'Germany',
'toponymName': 'Federal Republic of Germany'},
'3017382': {'countryCode': 'FR',
'countryName': 'France',
'fcl': 'A',
'fcode': 'PCLI',
'lat': '46',
'lng': '2',
'name': 'France',
'toponymName': 'Republic of France'},
'3042058': {'countryCode': 'LI',
'countryName': 'Liechtenstein',
'fcl': 'A',
'fcode': 'PCLI',
'lat': '47.16667',
'lng': '9.53333',
'name': 'Liechtenstein',
'toponymName': 'Principality of Liechtenstein'},
'3175395': {'countryCode': 'IT',
'countryName': 'Italy',
'fcl': 'A',
'fcode': 'PCLI',
'lat': '42.83333',
'lng': '12.83333',
'name': 'Italy',
'toponymName': 'Repubblica Italiana'}}
>>>
C'est assez simple dans l'ensemble.