Recherche sur le blog

vendredi 27 janvier 2012

[WD15] Utiliser un Webservice qui renvoie du XML

Aujourd'hui, présentation d'un cas plutôt intéressant, qui va nous faire découvrir des fonctions XML. Nous allons voir ici comment traiter la réponse d'un Webservice qui renvoie une chaîne au format XML et comment parcourir les différents éléments. Une deuxième solution sera également envisagée: l'utilisation de la fonction HImportXML, qui permet d'intégrer à une table (d'une base de données) le contenu d'un document XML, pour autant qu'il respecte une certaine structure. Pour vous aider, nous avons, en tant qu'exemple, importé et utilisé le Webservice "Global Weather", que l'on retrouve sur le site WebserviceX.NET.

Que va-t-on faire ici ? 

Le Webservice utilisé comme exemple ne sera pas détaillé et exploité dans son entièreté. Seul l'affichage d'une liste de couples "Pays/Ville" sera affichée, lorsqu'on saisira un nom partiel ou complet de pays dans un champ texte classique. Nous aurons donc une fenêtre, un champ de type "saisie", ainsi qu'un champ de type "combo" (liste déroulante). Si vous êtes un habitué de WinDev, vous pouvez déjà créer ces éléments et les nommer comme ceci :
  • Champ de saisie : SAI_Pays.
  • Liste déroulante : COMBO_Cities.
          
Importer le web service

Pour importer le web service, n'hésitez pas à suivre la procédure détaillée dans l'article suivant : importer un web service. Pour rappel, WinDev générera les types et les opérations adéquates, qui permettront d'affecter les paramètres d'appel, mais aussi de récupérer chacune des réponses.

Récupérer la liste des pays/villes

Comme vous êtes maintenant à l'aise avec les services web, vous devriez rapidement comprendre le code suivant, dans lequel on déclare trois variables : la première servira à contenir les paramètres, la seconde contiendra la réponse, et la troisième est une variable dans laquelle on stockera le nom du pays suivi du nom de la ville. 

          
On affecte alors le paramètre, "CountryName" dans ce cas, avec la valeur du champ "Nom du pays".  Ensuite, on appelle l'opération "GetCitiesByCountry" avec la liste de paramètres, puis on stocke le résultat dans la variable "réponse". On peut ensuite analyser la réponse en affichant ou bien en se plaçant en mode "debug". Dans notre cas, il s'agit d'une chaîne : on peut donc l'afficher (par exemple, avec Info).

         
Pour cette opération, nous avons obtenu un XML qui possède la structure suivante :

                     
Nous allons voir les différentes méthodes employées pour gérer cette réponse.

Solution 1 : parcourir le document XML

La première solution consiste à parcourir le document XML. Comment faire ? Depuis que la version 15 de WinDev est apparue, "parser" un document XML a été simplifié. On dispose d'un bon nombre de méthodes, telles que XMLSuivant, XMLTermine, XMLPremier, XMLDonnée, etc. Nous allons donc expliquer, avec un bouton de code, comment descendre et analyser chacune des données pour les ajouter à la liste. On ne passe donc pas par une quelconque table ! Notez bien qu'il s'agit d'une première ébauche, et que celle-ci pourrait sans doute être améliorée...


Qu'est-ce qui est réalisé ici ?
  • On initialise le document XML avec la réponse donnée par le service.
  • On lit le premier élément grâce à XMLPremier.
  • On effectue une boucle avec comme condition "tant que l'on n'est pas en dehors du document...". Pour cela on utilise une fonction appelée XMLEnDehors(document).
  • On vérifie que l'élément est "Table". Si ce n'est pas le cas, on va descendre d'un nœud grâce à la fonction XMLFils, puis lire l'élément qui suit. Si par contre, l'élément valait bien "Table", alors on descend encore d'un nœud.
  • Si l'élément précédent valait table, on descend d'un nœud, et on vérifie que l'élément suivant vaut "Country". Si c'est le cas, on ajoute la donnée à la variable "sLigne" grâce à XMLDonnée(document). On continue à descendre jusqu'à l'élément "City". Ensuite, on ajoutera à la liste et on remontera au parent (XMLParent), tout en effectuant une lecture supplémentaire.
  • Lorsqu'on sort de la boucle, on ferme le document (XMLTermine).
Notez que les fonctions comme XMLFils et XMLParent effectuent une lecture, donc ils se positionnent sur l'enregistrement suivant !

Testez votre fenêtre et saisissez un nom de pays (par exemple, "Belgium"). Ensuite, déroulez la liste pour voir le résultat. Si cela fonctionne et que vous obtenez quelque chose de similaire à la fenêtre ci-dessous, vous pouvez passer à la seconde solution.


Solution 2 : utiliser un fichier HyperFileSQL

Comme le document XML obtenu possède une structure bien spécifique, on va pouvoir importer celui-ci directement dans une table de base de données. Rappelons-nous la structure du fichier obtenu grâce à l'image suivante : 


D'après la documentation officielle de la fonction HImportXML, notre fichier, que nous allons soit décrire via l'analyse, soit par programmation, aurait dû s'appeler "NewDataSet" et contenir une rubrique nommée "Table" avec deux sous-rubriques. Cependant, les deux sous-rubriques de "Table" auraient dû être liées à deux sous-éléments "Table_1" et "Table_2". Ici, les sous-éléments sont "Country" et "City". Nous allons donc faire abstraction de l'élément "Table".

Au préalable, il est nécessaire de créer la table correspondante (NewDataSet - rubriques : Country [texte] - City [texte]) et réutiliser le code d'appel au service web avant d'insérer la partie qui suit.


Qu'est-ce qui est réalisé ici ? 
  • On déclare une chaine dans laquelle on va stocker le résultat, et rajouter une balise XML conforme en début de document.
  • On sauvegarde le tout dans un fichier texte avec l'extension XML.
  • On appelle la fonction HImportXML avec en paramètres, le nom de la table, et le chemin vers le fichier XML.
  • On lit le premier élément dans la table.
  • On ajoute un élément texte à la liste, qui est composé du pays, et de la ville.
  • On lit l'élément suivant jusqu'à arriver à la fin du fichier.
Si cela fonctionne, vous ne devriez pas obtenir d'erreur ou d'exception à l'exécution.

Bon développement !

Aucun commentaire: