Introduction par l'exemple à PHP 4


précédentsommairesuivant

V. XML et PHP

Dans ce chapitre, nous allons faire une introduction à l'utilisation de documents XML (eXtensible Markup Language) avec PHP. Nous le ferons dans le contexte de l'application impôts étudiée dans le chapitre précédent.

V-A. Fichiers XML et feuilles de style XSL

Considérons le fichier XML suivant qui pourrait représenter le résultat de simulations :

 
CacherSélectionnez

Si on le visualise avec IE 6, on obtient le résultat suivant :

Image non disponible

IE6 reconnaît qu'il a affaire à un fichier XML (grâce au suffixe .xml du fichier) et le met en page d'une façon qui lui est propre. Avec Netscape on obtient une page vide. Cependant si on regarde le code source (View/Source) on a bien le fichier XML d'origine :

Image non disponible

Pourquoi Netscape n'affiche-t-il rien ? Parce qu'il lui faut une feuille de style qui lui dise comment transformer le fichier XML en fichier HTML qu'il pourra alors afficher. Il se trouve que IE 6 a lui une feuille de style par défaut lorsque le fichier XML n'en propose pas ce qui était le cas ici.

Il existe un langage appelé XSL (eXtensible StyleSheet Language) permettant de décrire les transformations à effectuer pour passer un fichier XML en un fichier texte quelconque. XSL permet l'utilisation de nombreuses instructions et ressemble fort aux langages de programmation. Nous le détaillerons pas ici car il y faudrait plusieurs dizaines de pages. Nous allons simplement décrire deux exemples de feuilles de style XSL. La première est celle qui va transformer le fichier XML simulations.xml en code HTML. On modifie ce dernier afin qu'il désigne la feuille de style que pourront utiliser les navigateurs pour le transformer en document HTML qu'ils pourront afficher :

 
CacherSélectionnez

La commande XML

 
CacherSélectionnez

désigne le fichier simulations.xsl comme un feuille de style (xml-stylesheet) de type text/xsl c.a.d. un fichier texte contenant du code XSL. Cette feuille de style sera utilisée par les navigateurs pour transformer le texte XML en document HTML. Voici le résultat obtenu avec Netscape 7 lorsqu'on charge le fichier XML simulations.xml :

Image non disponible

Lorsque nous regardons le code source du document (View/Source) nous retrouvons le document XML initial et non le document HTML affiché :

Image non disponible

Netscape a utilisé la feuille de style simulations.xsl pour transformer le document XML ci-dessus en document HTML affichable. Il est maintenant temps de regarder le contenu de cette feuille de style :

 
CacherSélectionnez
  • une feuille de style XSL est un fichier XML et en suit donc les règles. Il doit être en autres choses "bien formé" c'est-à-dire que toute balise ouverte doit être fermée.
  • le fichier commence par deux commandes XML qu'on pourra garder dans toute feuille de style XSL sous Windows :
 
CacherSélectionnez

L'attribut encoding="windows-1252" permet d'utiliser les caractères accentués dans la feuille de style.

  • La balise <xsl:output method="html" indent="yes"/> indique à l'interpréteur XSL qu'on veut produire du HTML "indenté".
  • La balise <xsl:template match="élément"> sert à définir l'élément du document XML sur lequel vont s'appliquer les instructions que l'on va trouver entre <xsl:template …> et </xsl:template>.
 
CacherSélectionnez

Dans l'exemple ci-dessus l'élément "/" désigne la racine du document. Cela signifie que dès que le début du document XML va être rencontré, les commandes XSL situées entre les deux balises vont être exécutées.

  • Tout ce qui n'est pas balise XSL est mis tel quel dans le flux de sortie. Les balises XSL elles sont exécutées. Certaines d'entre-elles produisent un résultat dans le flux de sortie. Etudions l'exemple suivant :
 
CacherSélectionnez

Rappelons que le document XML analysé est le suivant :

 
CacherSélectionnez

Dès le début du document XML analysé (match="/"), l'interpréteur XSL va produire en sortie le texte

 
CacherSélectionnez

On remarquera que dans le texte initial on avait <hr/> et non pas <hr>. Dans le texte initial on ne pouvait pas écrire <hr> qui si elle est une balise HTML valide est une balise XML invalide. Or nous avons affaire ici à un texte XML qui doit être "bien formé", c.a.d que toute balise doit être fermée. On écrit donc <hr/> et parce qu'on a écrit <xsl:output text="html …> l'interpréteur transformera le texte <hr/> en <hr>. Derrière ce texte, viendra ensuite le texte produit par la commande XSL :

 
CacherSélectionnez

Nous verrons ultérieurement quel est ce texte. Enfin l'interpréteur ajoutera le texte :

 
CacherSélectionnez

La commande <xsl:apply-templates select="/simulations/simulation"/> demande qu'on exécute le "template" (modèle) de l'élément /simulations/simulation. Elle sera exécutée à chaque fois que l'interpréteur XSL rencontrera dans le texte XML analysé une balise <simulation>..</simulations> ou <simulation/> à l'intérieur d'une balise <simulations>..</simulations>. A la rencontre d'une telle balise, l'interpréteur exécutera les instructions du modèle suivant :

 
CacherSélectionnez

Prenons les lignes XML suivantes :

 
CacherSélectionnez

La ligne <simulation ..> correspond au modèle de l'instruction XSL <xsl:apply-templates select="/simulations/simulation>". L'interpréteur XSL va donc chercher à lui appliquer les instructions qui correspondent à ce modèle. Il va trouver le modèle <xsl:template match="simulation"> et va l'exécuter. Rappelons que ce qui n'est pas une commande XSL est repris tel quel par l'interpréteur XSL et que les commandes XSL sont elles remplacées par le résultat de leur exécution. L'instruction XSL <xsl:value-of select="@champ"/> est ainsi remplacé par la valeur de l'attribut "champ" du nœud analysé (ici un nœud <simulation>). L'analyse de la ligne XML précédente va produire en sortie le résultat suivant :

XSL sortie
<tr><td> <tr><td>
<xsl:value-of select="@marie"/> oui
</td><td> </td><td>
<xsl:value-of select="@enfants"/> 2
</td><td> </td><td>
<xsl:value-of select="@salaire"/> 200000
</td><td> </td><td>
<xsl:value-of select="@impot"/> 22504
</td></tr> </td></tr>

Au total, la ligne XML

 
CacherSélectionnez

va être transformée en ligne HTML :

 
CacherSélectionnez

Toutes ces explications sont un peu rudimentaires mais il devrait apparaître maintenant au lecteur que le texte XML suivant :

 
CacherSélectionnez

accompagné de la feuille de style XSL simulations.xsl suivante :

 
CacherSélectionnez

produit le texte HTML suivant :

 
CacherSélectionnez

Le fichier XML simulations.xml suivant

 
CacherSélectionnez

lu par un navigateur récent (ici Netscape 7) est alors affiché comme suit :

Image non disponible

V-B. Application impôts : version 5

V-B-1. Les fichiers XML et feuilles de style XSL de l'application impôts

Revenons à notre point de départ qui était l'application web impôts et rappelons que nous voulons la modifier afin que la réponse faite aux clients soit une réponse au format XML plutôt qu'une réponse HTML. Cette réponse HTML sera accompagnée d'une feuille de style XSL afin que les navigateurs puissent l'afficher. Dans le paragraphe précédent, nous avons présenté :

  1. le fichier simulations.xml qui est le prototype d'une réponse XML comportant des simulations de calculs d'impôts
  2. le fichier simulations.xsl qui sera la feuille de style XSL qui accompagnera cette réponse XML

Il nous faut prévoir également le cas de la réponse avec des erreurs. Le prototype de la réponse XML dans ce cas sera le fichier erreurs.xml suivant :

 
CacherSélectionnez

La feuille de style erreurs.xsl permettant d'afficher ce document XML dans un navigateur sera la suivante :

 
CacherSélectionnez

Cette feuille de style introduit une commande XSL non encore rencontrée : <xsl:value-of select="."/>. Cette commande produit en sortie la valeur du nœud analysé, ici un nœud <erreur>texte</erreur>. La valeur de ce nœud est le texte compris entre les deux balises d'ouverture et de fermeture, ici texte.

Le code erreurs.xml est transformé par la feuille de style erreurs.xsl en document HTML suivant :

 
CacherSélectionnez

Le fichier erreurs.xml accompagné de sa feuille de style est affiché par un navigateur de la façon suivante :

Image non disponible

V-B-2. L'application xmlsimulations

Nous créons un fichier xmlsimulations.html que nous mettons dans le répertoire de l'application impots. La page visualisée est la suivante :

Image non disponible

Ce document HTML est un document statique. Son code est le suivant :

 
CacherSélectionnez

On notera que les données du formulaire sont postées à l'URL /poly/impots/7/xmlsimulations.php. Le code de l'application xmlsimulations.php est très analogue à celui de l'application impots.php. Le lecteur est invité à revoir celui-ci. Rappelons le code d'entrée  :

 
CacherSélectionnez

Les pages HTML étaient affichées par les lignes include "…". On veut ici générer du XML et non du HTML. Il suffit d'écrire deux nouvelles applications impots_erreurs.php et impots_simulations.php pour qu'elle génèrent du XML au lieu du HTML. Le reste de l'application ne change pas. Le code devient alors le suivant :

 
CacherSélectionnez

Nous avons précédemment présenté et étudié les deux types de réponse XML à fournir ainsi que les feuilles de style qui doivent les accompagner. Le code de l'application impots_simulations.php est le suivant :

 
CacherSélectionnez

Ce code permet à partir du dictionnaire $requête de générer du code XML analogue au suivant :

 
CacherSélectionnez

La feuille de style simulations.xsl transformera ce code XML en code HTML.

Le code de l'application impots_erreurs.php est le suivant :

impots_erreurs.php
CacherSélectionnez

Ce code permet à partir du dictionnaire $requête de générer du code XML analogue au suivant :

 
CacherSélectionnez

La feuille de style erreurs.xsl transformera ce code XML en code HTML.

Voyons un premier exemple :

Image non disponible

Le SGBD MySQL n'est pas lancé. On reçoit alors la réponse suivante :

Image non disponible

Si on regarde le code source reçu par le navigateur, on a la chose suivante :

 
CacherSélectionnez

Maintenant, nous lançons le SGBD MySQL et faisons différentes simulations successives. Nous obtenons la réponse suivante :

Image non disponible

Le code reçu par le navigateur est le suivant :

 
CacherSélectionnez

On remarquera que notre nouvelle application est plus simple à maintenir que la précédente. Une partie du travail a été transférée sur les feuilles de style XSL. L'intérêt de cette nouvelle répartition des tâches est qu'une fois le format XML des réponses a été fixé, le développement des feuilles de style est indépendant de celui de l'application.

V-C. Analyse d'un document XML en PHP

La prochaine version de notre application impots va être un client programmé de l'application précédente xmlsimulations. Notre client va donc recevoir du code XML qu'il devra analyser pour en retirer les informations qui l'intéresse. Nous allons faire ici une pause dans nos différentes versions et apprendre comment on peut analyser un document XML en PHP. Nous le ferons à partir de l'exemple suivant :

 
CacherSélectionnez

L'application xmlParser.php admet un

paramètre : l'URI (Uniform Resource Identifier) du document XML à analyser. Dans notre exemple, cette URI sera simplement le nom d'un fichier XML placé dans le répertoire de l'application xmlParser.php. Considérons deux exemples d'exécution. Dans le premier exemple, le fichier XML analysé est le fichier erreurs.xml suivant :

 
CacherSélectionnez

L'analyse donne les résultats suivants :

 
CacherSélectionnez

Nous n'avions pas encore écrit ce que faisait l'application xmlParser.php mais l'on voit ici qu'elle affiche la structure du document XML analysé. Le second exemple analyse le fichier XML simulations.xml suivant :

 
CacherSélectionnez

L'analyse donne les résultats suivants :

 
CacherSélectionnez

L'application xmlParser.php contient tout ce dont nous avons besoin dans notre application impots puisqu'elle a été capable de retrouver soit les erreurs soit les simulations que pourrait envoyer le serveur web. Examinons son code :

 
CacherSélectionnez

Etudions le code se rapportant à XML. Pour analyser un document XML, notre application a besoin d'un analyseur de code XML appelé habituellement un "parseur".

 
CacherSélectionnez

Lorsque le parseur va analyser le document XML, il va émettre des événements tels que : j'ai rencontré le début du document, le début d'une balise, un attribut de balise, le contenu d'une balise, la fin d'une balise, la fin du document… Il transmet ces événements à des méthodes qu'on doit lui désigner :

 
CacherSélectionnez
événement émis par le parseur méthode de traitement
début d'un élément :<balise> function startElement($parser,$name,$attributs)
$parser : le parseur du document
$name : nom de l'élément analysé. Si l'élément rencontré est <simulations>, on aura name="simulations".
$attributs : liste des attributs de la balise sous la forme (ATTRIBUT,valeur) où ATTRIBUT est le nom en majuscules de la balise.
valeur d'un élément :
<balise>valeur</balise>
function afficheData($parser,$data)
$parser : le parseur du document
$data : les données de la balise
fin d'un élément : </balise> ou <balise …/> function endElement($parser,$name)
les paramètres sont ceux de la méthode startElement.

La fonction startElement permet de récupérer les attributs de l'élément grâce au paramètre $attributs. Celui-ci est un dictionnaire des attributs de la balise. Ainsi si on a la balise suivante :

 
CacherSélectionnez

le dictionnaire $attributs sera le suivant : array(marie=>oui,enfants=>2,salaire=>200000,impot=>22504)

Une fois définis le parseur, et les méthodes précédentes, l'analyse d'un document se fait la fonction xml_parse :

 
CacherSélectionnez
analyse d'un
document $doc
function xml_parse($parser,$doc,$fin)
le parseur $parser analyse le document $doc. $doc peut être un morceau d'un document plus important. Le paramètre $fin indique si c'est le dernier morceau (true) ou non (false). Lors de l'analyse du document $doc, les fonctions définies par xml_set_element_handler sont appelées à chaque début et fin de balise. La fonction définie par xml_set_character_data_handler est elle appelée à chaque fois que le contenu d'une balise a été obtenu.

Pendant l'analyse du document XML, il peut se produire des erreurs notamment si le document XML est "mal formé" par exemple lors de l'oubli de balises de fermeture. Dans ce cas, la fonction xml_parse rend une valeur évaluée à "faux" :

 
CacherSélectionnez
gestion d'erreurs function xml_get_error_code($parser)
rend le code de la dernière erreur survenue
function xml_ error_string($code)
rend le message d'erreur associé au code passé en paramètre
function xml_ get_current_line($parser)
rend le n° de la ligne du document XML en cours d'analyse par le parseur

Lorsque le document a été analysé, on libère les ressources attribuées au parseur :

 
CacherSélectionnez
libération des
ressources attribuées
au parseur $parser
function xml_free($parser)

Une fois ceci expliqué, le programme précédent accompagné des exemples d'exécution se comprend de lui-même.

V-D. Application impôts : version 6

Nous avons maintenant tous les éléments pour écrire un clients programmé pour notre service d'impôts qui délivre du XML. Nous reprenons la version 4 de notre application pour faire le client et nous gardons la version 5 pour ce qui est du serveur. Dans cette application client-serveur :

  • le service de simulations du calcul d'impôts est fait par l'application xmlsimulations.php. La réponse du serveur est donc au format XML comme nous l'avons vu dans la version 5.
  • le client n'est plus un navigateur mais un client php autonome. Son interface console est celle de la version 4.

Le lecteur est invité à relire le code de l'application cltImpots.php qui était le client programmé de la version 4. Celui-ci recevait un document $document du serveur. Celui-ci était alors un document HTML. C'est maintenant un document XML. Le document HTML $document était analysé par la fonction suivante :

 
CacherSélectionnez

La fonction recevait le document HTML $document, l'analysait et rendait un dictionnaire $impots à deux attributs :

  • erreurs : un tableau d'erreurs
  • simulations : un tableau de simulations, chaque simulation étant elle-même un tableau à quatre éléments (marie,enfants,salaire,impot).

L'application cltImpots.php devient maintenant cltXmlSimulations.php. Seule la partie qui traite le document reçu du serveur doit changer pour tenir compte du fait que c'est maintenant un document XML. La fonction getInfos devient alors la suivante :

 
CacherSélectionnez

Commentaires :

  • la fonction getInfos($document) commence par créer un parseur, puis le configure et enfin lance l'analyse du document $document :
     
    CacherSélectionnez
  • au retour de l'analyse, on libère les ressources allouées au parseur et on rend le dictionnaire $impots.
     
    CacherSélectionnez
  • la fonction startElement($parser,$name,$attributs) est appelée à chaque début de balise. Elle
    • note la balise $name dans un tableau de balises $balises. Ce tableau est géré comme une pile : à la rencontre du symbole de fin de balise, la dernière balise empilée dans $balises sera dépilée. La balise courante est également notée dans $balise. Dans le dictionnaire $attributs, on trouve les attributs de la balise rencontrée, ces attributs étant en majuscules.
    • enregistre les attributs dans le dictionnaire global $impots[simulations], s'il s'agit d'une balise de simulation.
  • la fonction getData($parser,$data) lorsque le contenu $data d'une balise a été récupéré. Ici, on a pris une précaution. Dans certaines API, notamment Java, de traitement de documents XML, il est indiqué que cette fonction peut être appelée de façon répétée, c.a.d. qu'on n'a pas forcément le contenu $data d'une balise en une seule fois. Ici, la documentation PHP n'indique pas cette restriction. Par précaution, on cumule la valeur $data obtenue à une variable globale $contenu. Ce n'est qu'à la rencontre du symbole de fin de balise qu'on estimera avoir obtenu l'intégralité du contenu de la balise. La seule balise concernée par ce traitement est la balise <erreur>.
  • la fonction endElement($parser,$name) est appelée à chaque fin de balise. Elle est utilisée ici pour changer le nom de la balise courante en enlevant la dernière balise de la pile de balises et pour ajouter le contenu de la balise <erreur> qui se termine au tableau $impots[erreurs].

Voici quelques exemples d'exécution, tout d'abord avec un SGBD qui n'a pas été lancé :

 
CacherSélectionnez

Puis avec le SGBD lancé :

 
CacherSélectionnez

V-E. Conclusion

Grâce à sa réponse XML l'application impots est devenue plus facile à gérer à la fois pour son concepteur que pour les concepteurs des application clientes.

  1. la conception de l'application serveur peut maintenant être confiée à deux types de personnes : le développeur PHP de la servlet et l'infographiste qui va gérer l'apparence de la réponse du navigateur dans les navigateurs. Il suffit à ce dernier de connaître la structure de la réponse XML du serveur pour construire les feuilles de style qui vont l'accompagner. Rappelons que celles-ci font l'objet de fichiers XSL à part et indépendants de l'aplication PHP. L'infographiste peut donc travailler indépendamment du développeur.
  2. les concepteurs des applications clientes ont eux aussi simplement besoin de connaître la structure de la réponse XML du serveur. Les modifications que pourrait apporter l'infographiste aux feuilles de style n'ont aucune répercussion sur cette réponse XML qui reste toujours la même. C'est un énorme avantage.
  3. Comment le développeur peut-il faire évoluer son application PHP sans tout casser ? Tout d'abord, tant que sa réponse XML ne change pas, il peut organiser son application comme il veut. Il peut aussi faire évoluer la réponse XML tant qu'il garde les éléments <erreur> et <simulation> attendus par ses clients. Il peut ainsi ajouter de nouvelles balises à cette réponse. L'infographiste les prendra en compte dans ses feuilles de style et les navigateurs pourront avoir les nouvelles versions de la réponse. Les clients programmés eux continueront à fonctionner avec l'ancien modèle, les nouvelles balises étant tout simplement ignorées. Pour que cela soit possible, il faut que dans l'analyse XML de la réponse du serveur, les balises cherchées soient bien identifiées. C'est ce qui a été fait dans notre client XML de l'application impôts où dans les procédures on disait spécifiquement qu'on traitait les balises <erreur> et <simulation>. Du coup les autres balises sont ignorées.

précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2001 Serge Tahé. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.