Python: Parser et indenter un flux XML

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.

Ajouter un commentaire

Filtered HTML

  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question permet de s'assurer que vous êtes un utilisateur humain et non un logiciel automatisé de pollupostage.
CAPTCHA visuel
Entrez les caractères (sans espace) affichés dans l'image.