Skip to Content

Nous adressons toutes nos pensées à la famille de notre ami Jérôme !

http://www.forumsig.org/showthread.php/43488-Disparition-de-Phoenix

XML et Python pour les Sigistes ou pourquoi il n'y a pas besoin de réinventer la roue...

Niveau Débutant
Logiciels utilisés Python
Plateforme Windows | Mac | Linux | FreeBSD

À l'heure où certains, sur des sites consacrés à Python pour ArcGis, s'évertuent encore à programmer en partant de zéro les traitements de fichiers XML en Python (de même que certains scripts qui peuvent être téléchargés sur les sites d'ESRI), il est bon de revenir aux fondamentaux des programmeurs Python et à la paresse (ne pas se fatiguer pour rien), même si le travail est louable.

En effet, depuis très longtemps les distributions de Python contiennent des modules destinés à traiter les fichiers XML et les tutoriels sont innombrables sur le Net. Mais, à force de considérer Python comme un simple langage de script pour ArcGis ou autre, il est peut-être difficile de l'imaginer (voir « Python: géospatial, dialectes (standard, pour ESRI, pour FME, pour GvSIG etc.) et incompréhensions...»).

Mais soyons concrets, parmi le très grand nombre de modules existants (pypi.python.org/pypi ou www.afpy.org/Members/anguenot/rmll2005/rmll2005_ja_python_xml.pdf), le plus facile à utiliser est ElementTree. Simple module supplémentaire dans les versions inférieures à la 2.5, il a depuis lors été intégré au module xml standard sous le nom xml.etree (ElementTree API) :

importation d'ElementTree

  1. try:
  2. from xml.etree import ElementTree as ET # Python >= 2.5
  3. except ImportError:
  4. import elementtree.ElementTree as ET # module Python originel

Cet API existe dans d'autres implémentations (lxml, par exemple) et code.activestate.com/recipes/475126-import-elementtree-from-everywhere/ montre toutes les possibilités d'importation pour n'importe quelle version de Python.

Application pratique

Les fichiers XML sont très nombreux dans le monde des SIGs, remplissant diverses fonctions. Nous allons traiter ici un fichier projet de Quantum Gis, d'extension .qgs.

Rien de plus facile, pas besoin d'effectuer des traitements plus ou moins tarabiscotés.

traitement d'un fichier .qgs (XML)

  1. with open('test.qgs', 'r') as f:
  2. arbre = ET.parse(f)

Et c'est tout, l'ensemble du fichier et sa structure hiérarchique sont codés dans la variable arbre, puisqu'un fichier XML est un arbre hiérarchique.

 

Le module va en fait décomposer le fichier XML en un arbre d'éléments (d'où le nom). Chaque branche (élément) peut alors être directement atteinte. Dans le but de modifier automatiquement les chemins des fichiers renseignés dans ce fichier .qgs, j'ai donc créé un script. Ces chemins  sont dans la branche <projectlayers> (il y en a 2 ici, « layercount="2"»).

Chaque sous-branche de maplayer se présente graphiquement de la manière suivante :

Je recherche bien évidemment à récupérer la valeur de  <datasource> pour la modifier.

recherche

  1. # quels sont les attributs d'un maplayer ?
  2.  
  3. at = arbre.find( './/projectlayers/maplayer')
  4. at.attrib
  5. {'maximumScale': '1e+08', 'hasScaleBasedVisibilityFlag': '0', 'type': 'raster', 'minimumScale': '0'}
  6.  
  7. # c'est donc type qui indique la nature de la couche
  8. # recherche des couches
  9.  
  10. for elem in arbre.findall('.//projectlayers/maplayer/'):
  11. # attribut type
  12. print("type :"),elem.attrib["type"]
  13. print("nom :"), elem.find('layername').text
  14. print("source : "), elem.find('datasource').text
  15.  
  16. type : raster
  17. nom : test raster
  18. source : /Users/Shared/test.tif
  19.  
  20. type : vector
  21. nom : test shape
  22. source : /Users/Shared/test.shp

ce qui signifie :

  1. aller dans la sous-branche qgis/projectlayers/maplayer
  2. afficher le contenu de l'attribut « type »
  3. afficher le contenu des éléments « layername» et « datasource »

Vous me direz alors, facile avec les figures ! Mais elles ne sont là que pour illustrer le propos et ElementTree permet de lister toutes les branches, de les atteindre et/ou de les modifier, si nécessaire. J'aurais pu tout faire en Python mais cela aurait été moins parlant.

De la même manière, il est très facile de créer un nouveau fichier XML et/ou de remplacer le texte des éléments,  comme les chemins des fichiers dans <datasource>. Le script résultant fait quelques lignes et il peut même être effectué dans la console Python de Qgis, avant ouverture d'un projet provenant d'une autre machine, pour autant que les éléments soient disponibles.

Conclusions

Pour la suite, je vous invite à apprendre avec les innombrables tutoriels disponibles depuis longtemps. Surtout qu'après tant d'années, les développeurs pour ESRI semblent enfin avoir découvert les joies de la paresse (www.forumsig.org/showthread.php, blogs.esri.com/Dev/blogs/geoprocessing/archive/2010/05/07/Handling-XML-with-Python-in-ArcGIS.aspx) ...

Ce module permet de traiter tous les types de fichiers XML, comme les fichiers KML les fichiers GPX ou SVG  en passant par tous les autres. Une fois la procédure bien assimilée cela devient très facile. Il est aussi à la base de beaucoup d'autres modules spécialisés.

Tous les traitements ont été effectués sur Mac OS X et  avec Python 2.6.1 et Freeplane (freeplane.sourceforge.net/wiki/index.php/Main_Page) ou Freemind (freemind.sourceforge.net/wiki/index.php/Main_Page) pour la représentation graphique des fichiers XML et « Le droit à la paresse » de Paul Lafargue (1842-1911).

Site officiel : module ElementTree originel
Site officiel : ElementTree API dans xml.etree
Site officiel : ElementTree API dans le module lxml
Autres Liens : Python: géospatial, dialectes (standard, pour ESRI, pour FME, pour GvSIG etc.) et incompréhensions...
Autres Liens : Le droit à la paresse (téléchargeable)


Creative Commons License
licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique Commerciale 2.0 France

Commentaires

Poster un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.