Manuel PHP

Table des matières

Préface
I. Au moment de commencer
II. Installation et configuration
III. Référence du langage
IV. Sécurité
V. Caractéristiques
VI. Référence des fonctions
VII. PHP et le moteur interne Zend
VIII. FAQ : foire Aux Questions
IX. Annexes
Remerciements



CLXXVI. Analyseur syntaxique XML

Introduction

Le langage XML (eXtensible Markup Language (Langage à Balises Extensible)) est un format structuré de données pour les échanges sur le web. C’est un standard défini par le consortium World Wide Web (W3C). Plus d’informations à propos du XML et des technologies afférentes sont accessibles (en anglais) http://www.w3.org/XML/.

Cette extension vous permet de créer des analyseurs XML puis de définir des gestionnaires pour chaque événement XML. Les analyseurs XML disposent de quelques paramètres que vous pouvez régler.

Pré-requis

Cette extension PHP utilise expat compat layer par défaut. Elle peut aussi utiliser expat, qui est disponible sur http://www.jclark.com/xml/expat.html. Le fichier Makefile livré avec expat ne construit pas par défaut de bibliothèque : il faut utiliser la ligne suivante :

libexpat.a: $(OBJS) ar -rc $@ $(OBJS) ranlib $@

Un paquet RPM source de expat est disponible sur http://sourceforge.net/projects/expat/.

Installation

Ces fonctions sont activées par défaut, et utilisent la bibliothèque expat fournie avec la distribution. Vous pouvez désactiver le support de XML en utilisant l’option de compilation “–disable-xml”. Si vous compilez PHP comme module pour Apache 1.3.9 ou supérieur, PHP va automatiquement utiliser la bibliothèque expat fournie par Apache. Si vous ne souhaitez pas utiliser la bibliothèque expat intégrée, il faut que vous compiliez PHP avec l’option “–with-expat-dir=DIR”, où DIR est le dossier d’installation de votre bibliothèque expat.

La version Windows de PHP dispose du support automatique de cette extension. Vous n’avez pas à ajouter de bibliothèque supplémentaire pour disposer de ces fonctions.

Configuration à l'exécution

Cette extension ne définit aucune directive de configuration.

Types de ressources

"xml"

La ressource “xml” est retournée par xml_parser_create() et xml_parser_create_ns(), et représente un analyseur XML à utiliser avec les autres fonctions de cette extension.

Constantes pré-définies

Ces constantes sont définies par cette extension, et ne sont disponibles que si cette extension a été compilée avec PHP, ou bien chargée au moment de l’exécution.

XML_ERROR_NONE” (entier)

XML_ERROR_NO_MEMORY” (entier)

XML_ERROR_SYNTAX” (entier)

XML_ERROR_NO_ELEMENTS” (entier)

XML_ERROR_INVALID_TOKEN” (entier)

XML_ERROR_UNCLOSED_TOKEN” (entier)

XML_ERROR_PARTIAL_CHAR” (entier)

XML_ERROR_TAG_MISMATCH” (entier)

XML_ERROR_DUPLICATE_ATTRIBUTE” (entier)

XML_ERROR_JUNK_AFTER_DOC_ELEMENT” (entier)

XML_ERROR_PARAM_ENTITY_REF” (entier)

XML_ERROR_UNDEFINED_ENTITY” (entier)

XML_ERROR_RECURSIVE_ENTITY_REF” (entier)

XML_ERROR_ASYNC_ENTITY” (entier)

XML_ERROR_BAD_CHAR_REF” (entier)

XML_ERROR_BINARY_ENTITY_REF” (entier)

XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF” (entier)

XML_ERROR_MISPLACED_XML_PI” (entier)

XML_ERROR_UNKNOWN_ENCODING” (entier)

XML_ERROR_INCORRECT_ENCODING” (entier)

XML_ERROR_UNCLOSED_CDATA_SECTION” (entier)

XML_ERROR_EXTERNAL_ENTITY_HANDLING” (entier)

XML_OPTION_CASE_FOLDING” (entier)

XML_OPTION_TARGET_ENCODING” (entier)

XML_OPTION_SKIP_TAGSTART” (entier)

XML_OPTION_SKIP_WHITE” (entier)

gestionnaires d'événements

Les gestionnaires d’événements XML sont :

Tableau 1. Les gestionnaires d’événements XML supportés

Fonction PHP de configuration du gestionnaire Description de l’événement
xml_set_element_handler() Un événement est généré à chaque fois que l’analyseur XML rencontre une balise de début ou de fin. Deux gestionnaires sont disponibles : un pour le début, et un pour la fin.
xml_set_character_data_handler() “Character data” correspond grosso modo à tout ce qui n’est pas une balise XML, y compris les espaces entre les balises. Notez bien que l’analyseur XML n’ajoute ou n’efface aucun espace, et que c’est à l’application (c’est-à-dire vous) de décider de la signification de ces espaces.
xml_set_processing_instruction_handler() Les programmeurs PHP sont habitués aux instructions exécutables (processing instructions ou PIs). <?php ?> est une instruction exécutable où “php” est appelé programme cible. Ces instructions sont gérées de manière spécifique, (sauf le programme cible “XML” qui est réservé).
xml_set_default_handler() Tout ce qui n’a pas trouvé de gestionnaire est transmis au gestionnaire par défaut. Vous retrouverez par exemple, les déclarations de type de document dans ce gestionnaire.
xml_set_unparsed_entity_decl_handler() Ce gestionnaire est appelé pour gérer les déclaration des entités non analysées (NDATA).
xml_set_notation_decl_handler() Ce gestionnaire est appelé pour déclarer les notations.

Problèmes de casse

Les fonctions de gestion des balises peuvent rencontrer des balises en minuscule, majuscule ou encore dans un mélange des deux. En XML, la procédure standard est d’“identifier les séquences de caractères qui ne sont pas reconnues comme majuscule, et de les remplacer par leur équivalent majuscule”. En d’autres termes, XML met toutes les lettres en majuscules.

Par défaut, tous les noms des éléments qui sont transmis aux fonctions de gestion sont mises en majuscule. Ce comportement est contrôlé par l’analyseur XML, et peut être lu et modifié avec les fonctions respectives xml_parser_get_option() et xml_parser_set_option().

Codes d'erreurs

Les constantes suivantes sont définies comme des codes d’erreurs XML : (retournées par xml_parse())

XML_ERROR_NONE
XML_ERROR_NO_MEMORY
XML_ERROR_SYNTAX
XML_ERROR_NO_ELEMENTS
XML_ERROR_INVALID_TOKEN
XML_ERROR_UNCLOSED_TOKEN
XML_ERROR_PARTIAL_CHAR
XML_ERROR_TAG_MISMATCH
XML_ERROR_DUPLICATE_ATTRIBUTE
XML_ERROR_JUNK_AFTER_DOC_ELEMENT
XML_ERROR_PARAM_ENTITY_REF
XML_ERROR_UNDEFINED_ENTITY
XML_ERROR_RECURSIVE_ENTITY_REF
XML_ERROR_ASYNC_ENTITY
XML_ERROR_BAD_CHAR_REF
XML_ERROR_BINARY_ENTITY_REF
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
XML_ERROR_MISPLACED_XML_PI
XML_ERROR_UNKNOWN_ENCODING
XML_ERROR_INCORRECT_ENCODING
XML_ERROR_UNCLOSED_CDATA_SECTION
XML_ERROR_EXTERNAL_ENTITY_HANDLING

Codage des caractères

L’extension XML de PHP supporte les caractères Unicode grâce à différents codages. Il y a deux types de codages de caractères : le codage à la source et le codage à la cible. PHP utilise le “UTF-8” comme représentation interne.

L’encodage à la source est effectué lors de l'analyse du fichier par XML. Lors de la création d'un analyseur XML), un type de codage à la source peut être spécifié (et il ne pourra plus être modifié jusqu’à la destruction de l’analyseur). Les codages supportés sont : “ISO-8859-1”, “US-ASCII” et “UTF-8”. Les deux derniers sont des codages à un seul octet, c’est-à-dire que les caractères sont représentés sur un seul octet. “UTF-8” peut représenter des caractères composés par un nombre variable de bits (jusqu’à 21), allant de 1 à quatre octets. Le codage par défaut utilisé par PHPISO-8859-1”.

Le codage à la cible est effectué lorsque PHP transfert les données aux gestionnaires XML. Lorsqu’un analyseur est créé, le codage à la cible est spécifié de la même façon que le codage à la source, mais il peut être modifié à tout moment. Le codage à la cible affectera les balises, tout comme les données brutes, et les noms des instructions exécutables.

Si l’analyseur XML rencontre un caractère qu’il ne connaît pas (hors limite, par exemple), il retournera une erreur.

Si PHP rencontre un caractère dans le document XML analysé, qu’il ne peut pas représenter dans le codage à la cible choisi, le caractère sera remplacé par un point d’interrogation (cette attitude est susceptible de changer ultérieurement).

Exemples

Voici quelques exemples de code PHP analysant un document XML.

Exemple de structure XML

Ce premier exemple affiche la structure de l’élément de début dans un document avec indentation.

Exemple 1. Afficher une structure XML

<?php
$file = "donnees.xml";
$depth = array();
 
function debutElement($parser, $name, $attrs)
{
    global $depth;
    for ($i = 0; $i < $depth[$parser]; $i++) {
        echo "  ";
    }
    echo "$name\n";
    $depth[$parser]++;
}
 
function finElement($parser, $name)
{
    global $depth;
    $depth[$parser]--;
}
 
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "debutElement", "finElement");
if (!($fp = fopen($file, "r"))) {
    die("Impossible d'ouvrir le fichier XML");
}
 
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("erreur XML : %s à la ligne %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
?>

Transtypage XML -> HTML

Exemple 2. Transtypage XMLHTML

Cet exemple remplace les balises XML d’un document par des balises HTML. Les éléments inconnus seront ignorés. Bien entendu, cet exemple sera appliqué à un type précis de fichiers XML.

<?php
$file = "data.xml";
$map_array = array(
    "BOLD"     => "B",
    "EMPHASIS" => "I",
    "LITERAL"  => "TT"
);
 
function startElement($parser, $name, $attrs)
{
    global $map_array;
    if (isset($map_array[$name])) {
        echo "<$map_array[$name]>";
    }
}
 
function endElement($parser, $name)
{
    global $map_array;
    if (isset($map_array[$name])) {
        echo "</$map_array[$name]>";
    }
}
 
function characterData($parser, $data)
{
    echo $data;
}
 
$xml_parser = xml_parser_create();
// Utilisons la gestion de casse, de manière à être sûrs de trouver la balise dans $map_array
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($file, "r"))) {
    die("Impossible de trouver le fichier XML");
}
 
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("erreur XML : %s à la ligne %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
?>

Entité externe

Cet exemple exploite les références externes de XML : il est possible d’utiliser un gestionnaire d’entité externe pour inclure et analyser les documents, tous comme les instructions exécutables peuvent servir à inclure et analyser d’autres documents, et aussi fournir une indication de confiance (voir plus bas).

Le document XML qui est utilisé dans cet exemple est fourni plus loin dans l’exemple (”xmltest.xml” et “xmltest2.xml”).

Exemple 3. Entité externe

<?php
$file = "xmltest.xml";
 
function trustedFile($file)
{
    // faites seulement confiance aux fichiers locaux dont vous êtes le propriétaire
    if (!eregi("^([a-z]+)://", $file)
        && fileowner($file) == getmyuid()) {
            return true;
    }
    return false;
}
 
function startElement($parser, $name, $attribs)
{
    echo "&lt;<font color=\"#0000cc\">$name</font>";
    if (count($attribs)) {
        foreach ($attribs as $k => $v) {
            echo " <font color=\"#009900\">$k</font>=\"<font
                   color=\"#990000\">$v</font>\"";
        }
    }
    echo "&gt;";
}
 
function endElement($parser, $name)
{
    echo "&lt;/<font color=\"#0000cc\">$name</font>&gt;";
}
 
function characterData($parser, $data)
{
    echo "<strong>$data</strong>";
}
 
function PIHandler($parser, $target, $data)
{
    switch (strtolower($target)) {
        case "php":
            global $parser_file;
            // si le document analysé est de confiance, nous déclarons qu'il est sûr 
            // d'exécuter le code PHP qu'il contient. Si ce n'est pas le cas, le code est affiché
            // à la place.
            if (trustedFile($parser_file[$parser])) {
                eval($data);
            } else {
                printf("Untrusted PHP code: <em>%s</em>",
                        htmlspecialchars($data));
            }
            break;
    }
}
 
function defaultHandler($parser, $data)
{
    if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") {
        printf('<font color="#aa00aa">%s</font>',
                htmlspecialchars($data));
    } else {
        printf('<font size="-1">%s</font>',
                htmlspecialchars($data));
    }
}
 
function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId,
                                  $publicId) {
    if ($systemId) {
        if (!list($parser, $fp) = new_xml_parser($systemId)) {
            printf("Could not open entity %s at %s\n", $openEntityNames,
                   $systemId);
            return false;
        }
        while ($data = fread($fp, 4096)) {
            if (!xml_parse($parser, $data, feof($fp))) {
                printf("erreur XML : %s à la ligne %d lors de l'analyse de l'entité %s\n",
                       xml_error_string(xml_get_error_code($parser)),
                       xml_get_current_line_number($parser), $openEntityNames);
                xml_parser_free($parser);
                return false;
            }
        }
        xml_parser_free($parser);
        return true;
    }
    return false;
}
 
function new_xml_parser($file)
{
    global $parser_file;
 
    $xml_parser = xml_parser_create();
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");
    xml_set_processing_instruction_handler($xml_parser, "PIHandler");
    xml_set_default_handler($xml_parser, "defaultHandler");
    xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");
 
    if (!($fp = @fopen($file, "r"))) {
        return false;
    }
    if (!is_array($parser_file)) {
        settype($parser_file, "array");
    }
    $parser_file[$xml_parser] = $file;
    return array($xml_parser, $fp);
}
 
if (!(list($xml_parser, $fp) = new_xml_parser($file))) {
    die("Impossible d'ouvrir le fichier XML");
}
 
echo "<pre>";
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("Erreur XML : %s à la ligne %d\n",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
echo "</pre>";
echo "parse complete\n";
xml_parser_free($xml_parser);
 
?>

Exemple 4. xmltest.xml <?xml version=’1.0’?> <!DOCTYPE chapter SYSTEM “/just/a/test.dtd” [ <!ENTITY plainEntity “FOO entity”> <!ENTITY systemEntity SYSTEM “xmltest2.xml”> ]> <chapter> <TITLE>Title &plainEntity;</TITLE> <para> <informaltable> <tgroup cols=”3”> <tbody> <row><entry>a1</entry><entry morerows=”1”>b1</entry><entry>c1</entry></row> <row><entry>a2</entry><entry>c2</entry></row> <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row> </tbody> </tgroup> </informaltable> </para> &systemEntity; <section id=”about”> <title>A propos de ce document</title> <para> <!– Ceci est un commentaire –> <?php print ‘Salut! Ceci est PHP version ‘.phpversion(); ?> </para> </section> </chapter>

Ce fichier est inclus depuis “xmltest.xml”:

Exemple 5. xmltest2.xml <?xml version=”1.0”?> <!DOCTYPE foo [ <!ENTITY testEnt “test entity”> ]> <foo> <element attrib=”value”/> &testEnt; <?php print “Ceci est du code PHP qui est exécuté.”; ?> </foo>

Table des matières

utf8_decode – Convertit une chaîne UTF-8 en ISO-8859-1utf8_encode – Convertit une chaîne ISO-8859-1 en UTF-8xml_error_string – Lit le message d’erreur de l’analyseur XMLxml_get_current_byte_index – Retourne l’index de l’octet courant d’un analyseur XMLxml_get_current_column_number –  Retourne le nombre courant de la colonne d’un analyseur XML xml_get_current_line_number – Retourne le numéro de ligne courant d’un analyseur XMLxml_get_error_code – Récupère le code erreur de l’analyseur XMLxml_parse_into_struct – Analyse une structure XMLxml_parse – Commence l’analyse d’un document XMLxml_parser_create_ns – Crée un analyseur XMLxml_parser_create – Création d’un analyseur XMLxml_parser_free – Détruit un analyseur XMLxml_parser_get_option – Lit les options d’un analyseur XMLxml_parser_set_option – Affecte les options d’un analyseur XMLxml_set_character_data_handler – Affecte les gestionnaires de texte littéralxml_set_default_handler – Affecte le gestionnaire XML par défautxml_set_element_handler – Affecte les gestionnaires de début et de fin de balise XMLxml_set_end_namespace_decl_handler – Configure le gestionnaire XML de donnéesxml_set_external_entity_ref_handler – Configure le gestionnaire XML de références externesxml_set_notation_decl_handler – Configure le gestionnaire XML de notationsxml_set_object –  Utilise un analyseur XML à l’intérieur d’un objet xml_set_processing_instruction_handler –  Affecte les gestionnaires d’instructions exécutables xml_set_start_namespace_decl_handler – Configure le gestionnaire de caractèresxml_set_unparsed_entity_decl_handler –  Affecte les gestionnaires d’entités non déclarées

Travail collaboratif

Contribuez, en ajjoutant des elements a cette page de manuel :

Merci de votre aide
L’equipe Php.fr

 


Index | Afficher le texte source | Anciennes révisions | Derniers changements | Connexion
©2007 Wiki Copyright