6.Le langage PHP

6.17.Parser un document XML

6.17.2.Parseur de type "SAX parser"

6.17.2.3.Amélioration avec xml_set_character_data_handler() et xml_set_element_handler()

Pour savoir si le texte rencontré est lié à une balise <item> ou <link> il faut se servir de la détection par le "parseur" des balises ouvrantes (et éventuellement fermantes).
Pour cela, nous devons donc créer une fonction chargée de traiter le cas des balises ouvrantes. Celle-ci sera appelée par le "parseur" avec trois paramètres: l'identifiant du parseur, le nom de la balise ouvrante rencontrée et le tableau des attributs de la balise. Cette fonction doit être déclarée auprès du "parseur" à l'aide de la fonction xml_set_element_handler() qui attend 3 paramètres: l'identifiant du parseur, le nom de la fonction traitant les balises ouvrantes et le nom de la fonction traitant les balises fermantes. La fonction en charge des balises fermantes est quant à elle appelée avec deux paramètres: l'identifiant du parseur et le nom de la balise fermante rencontrée.
Notre script peut donc être amélioré de la manière suivante:
<?php
    $fichier = "http://www.phpfacile.com/exemples_live/fluxrss.rss";

    // Ma propre fonction de traitement des balises ouvrantes
    function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
    {
        // En fait... nous nous conteterons de mémoriser le nom de la balise
        // afin d'en tenir compte dans la fonction "fonctionTexte"

        global $derniereBaliseRencontree;

        $derniereBaliseRencontree = $nomBalise;
    }
   
    // Ma propre fonction de traitement des balises fermantes
    function fonctionBaliseFermante($parseur, $nomBalise)
    {
        // On oublie la dernière balise rencontrée
        global $derniereBaliseRencontree;

        $derniereBaliseRencontree = "";
    }

    // Ma propre fonction de traitement du texte
    // qui est appelée par le "parseur"
    function fonctionTexte($parseur, $texte)
    {
        global $derniereBaliseRencontree;
        
        // Selon les cas, nous affichons le texte
        // ou nous proposons un lien
        // ATTENTION: Par défaut les noms des balises sont
        //            mises en majuscules
        
        switch ($derniereBaliseRencontree) {
            case "TITLE": 
                echo $texte;
                break;
            case "LINK":
                echo ":<a href=\"$texte\">L'article complet</a><br />";
                break;
        }         
    }

    // Création du parseur XML
    $parseurXML = xml_parser_create();

    // Je précise le nom des fonctions à appeler
    // lorsque des balises ouvrantes ou fermantes sont rencontrées
    xml_set_element_handler($parseurXML, "fonctionBaliseOuvrante"
                                       , "fonctionBaliseFermante");

    // Je précise le nom de la fonction à appeler
    // lorsque du texte est rencontré
    xml_set_character_data_handler($parseurXML, "fonctionTexte");

    // Ouverture du fichier
    $fp = fopen($fichier, "r");
    if (!$fp) die("Impossible d'ouvrir le fichier XML");

    // Lecture ligne par ligne
    while ( $ligneXML = fgets($fp, 1024)) {
        // Analyse de la ligne
        // REM: feof($fp) retourne TRUE s'il s'agit de la dernière
        //      ligne du fichier.
        xml_parse($parseurXML, $ligneXML, feof($fp)) or
            die("Erreur XML");
    }
    
    xml_parser_free($parseurXML);
    fclose($fp);
?>
Ce qui donne
ToutEstFacile - Exemple de flux RSS:L'article complet
Les cours PHP:L'article complet
Les cours SQL:L'article complet
Les cours XML:L'article complet
Voilà, nous ne sommes vraiment pas loin de la solution. Reste qu'il serait bon de distinguer le lien vers le site, des liens vers les articles et pourquoi ne pas plutot mettre les liens directement sur les titres plutôt qu'à coté.

6.17.2.4.Le "parseur" complet

Et bien, en fait, dans ce chapitre, vous n'apprendrez rien de nouveau (en tout cas, pas de nouvelles fonctions). Pour parvenir à nos besoins, ils suffit de bien analyser le problème, voir ce dont on dispose et ce dont on a besoin. En l'occurence, ici, nous ne connaissons le lien associé à un article qu'après en avoir eu le titre ce qui ne nous permet pas d'afficher les éléments au fur et à mesure dans le cas où l'on souhaite créer des liens du type <a href="lien">titre</a> il faut donc mémoriser les informations avant de les afficher et savoir quand les afficher.
Notre script complet devient alors:
<?php
    $fichier = "http://www.phpfacile.com/exemples_live/fluxrss.rss";

    // Ma propre fonction de traitement des balises ouvrantes
    function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
    {
        // En fait... nous nous conteterons de mémoriser le nom de la balise
        // afin d'en tenir compte dans la fonction "fonctionTexte"

        global $derniereBaliseRencontree;

        $derniereBaliseRencontree = $nomBalise;
    }
   
    // Ma propre fonction de traitement des balises fermantes
    function fonctionBaliseFermante($parseur, $nomBalise)
    {
        global $derniereBaliseRencontree;
        global $titre;
        global $lien;

        switch ($nomBalise) {
            case "CHANNEL" :
                // nous quittons le bloc channel
                // nous pouvons afficher le titre de notre
                // liste de d'articles
                echo "<center><b>Les dernieres nouvelles issues de ".
                     "<a href=\"$lien\">$titre</a></b></center>";
                // Et on oublie     
                $titre = "";
                $lien = "";
                break;
            case "ITEM" :
                // nous quittons un bloc item
                // nous pouvons afficher le titre de l'article
                echo "- <a href=\"$lien\">$titre</a><br />";
                // et on oublie
                $titre = "";
                $lien = "";
                break;
        }
        
        // On oublie la dernière balise rencontrée
        // et tout le reste
        $derniereBaliseRencontree = "";
    }

    // Ma propre fonction de traitement du texte
    // qui est appelée par le "parseur"
    function fonctionTexte($parseur, $texte)
    {
        global $derniereBaliseRencontree;
        global $titre;
        global $lien;
        
        // Nous n'affichons pas le texte ou lien directement
        // nous attendrons de rencontrer la balise fermante
        // et ainsi d'avoir tous les éléments avant l'affichage.
        // ATTENTION: Par défaut les noms des balises sont
        //            mises en majuscules
        
        switch ($derniereBaliseRencontree) {
            case "TITLE": 
                $titre = $texte;
                break;
            case "LINK":
                $lien = $texte;
                break;
        }         
    }

    // Création du parseur XML
    $parseurXML = xml_parser_create();

    // Je précise le nom des fonctions à appeler
    // lorsque des balises ouvrantes ou fermantes sont rencontrées
    xml_set_element_handler($parseurXML, "fonctionBaliseOuvrante"
                                       , "fonctionBaliseFermante");

    // Je précise le nom de la fonction à appeler
    // lorsque du texte est rencontré
    xml_set_character_data_handler($parseurXML, "fonctionTexte");

    // Ouverture du fichier
    $fp = fopen($fichier, "r");
    if (!$fp) die("Impossible d'ouvrir le fichier XML");

    // Lecture ligne par ligne
    while ( $ligneXML = fgets($fp, 1024)) {
        // Analyse de la ligne
        // REM: feof($fp) retourne TRUE s'il s'agit de la dernière
        //      ligne du fichier.
        xml_parse($parseurXML, $ligneXML, feof($fp)) or
            die("Erreur XML");
    }
    
    xml_parser_free($parseurXML);
    fclose($fp);
?>
Et voilà!
Ici vous pouvez apprendre :
1.Introduction
2.Installation de PHP
3.Exécuter un script PHP
4.Configuration et environnement d'exécution de PHP
5.L'environnement de développement
6.Le langage PHP
6.1.Introduction
6.2.Mon premier script
6.3.La syntaxe
6.4.Les boucles (for, while, foreach, do) en PHP
6.5.Les tableaux (array) en PHP
6.6.Les fonctions
6.7.Include
6.8.Programmation orientée objet
6.9.Les fonctions de manipulation de tableaux
6.10.Les dates
6.11.Fichiers et répertoires
6.12.Les paramètres d'entrée d'un script PHP
6.13.Utilisation de la librairie graphique
6.14.JpGraph pour tracer courbes et diagrammes
6.15.Utilisation de bases de données avec PHP
6.16.LDAP
6.17.Parser un document XML
6.17.1.Introduction
6.17.2.Parseur de type "SAX parser"
6.17.2.1.Principe du "parseur" XML
6.17.2.2.Mise en place avec xml_parser_create() et xml_parse()
6.17.2.3.Amélioration avec xml_set_character_data_handler() et xml_set_element_handler()
6.17.2.4.Le "parseur" complet
6.17.3.A partir de l'arbre DOM
6.17.4.Transformer un document XML avec XSL
6.18.Génération de documents PDF en PHP
6.19.Envoyer un mail
6.20.Créer un webmail avec IMAP
6.21.Droits utilisateurs: chmod 777
6.22.Localization (l10n) et Traduction
7.PHP pour le web
8.Internationalisation (i18n) et encodage en PHP
9.Créer un fichier de logs/traces
10.Déboguer une application PHP
11.Programmer en PHP en toute sécurité
12.Bibilothèque PEAR
13.Zend Framework 2 et 3
14.Installation de Zend Framework 2
15.Joomla
16.Composer
17.PHPUnit
18.PHPDocumentor
19.Mesure de temps d'exécution (benchmark) d'une fonction PHP
20.Exemples de scripts PHP
21.Erreurs fréquentes et les solutions
22.Archives
Version imprimable: imprimer