Files
doc-fr/reference/xml/reference.xml
2007-12-10 17:10:15 +00:00

633 lines
20 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.20 $ -->
<!-- EN-Revision: 1.19 Maintainer: gui Status: ready -->
<!-- Reviewed: yes -->
<!-- Purpose: xml -->
<!-- Membership: bundled, external -->
<reference xml:id="ref.xml" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Analyseur syntaxique XML</title>
<titleabbrev>XML</titleabbrev>
<partintro>
<section xml:id="xml.intro">
&reftitle.intro;
<para>
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)
<link xlink:href="&url.xml;">&url.xml;</link>.
</para>
<para>
Cette extension &php; implémente la bibliothèque <productname>expat</productname>
de James Clark sous &php;. Cela vous permettra d'analyser mais
pas de valider les documents XML. Ce langage supporte trois types de
<link linkend="xml.encoding">jeux de caractères</link> différents,
disponibles aussi sous &php; : <literal>US-ASCII</literal>, <literal>ISO-8859-1</literal>
et <literal>UTF-8</literal>. <literal>UTF-16</literal> n'est pas supporté.
</para>
<para>
Cette extension vous permet de créer des
<link linkend="function.xml-parser-create">analyseurs XML</link>
puis de définir des <emphasis>gestionnaires</emphasis>
pour chaque événement XML. Les analyseurs XML disposent
de quelques <link linkend="function.xml-parser-set-option">paramètres</link>
que vous pouvez régler.
</para>
</section>
<section xml:id="xml.requirements">
&reftitle.required;
<para>
Cette extension &php; utilise <productname>expat compat layer</productname>
par défaut. Elle peut aussi utiliser <productname>expat</productname>, qui est
disponible sur <link xlink:href="&url.expat;">&url.expat;</link>.
Le fichier Makefile livré avec <productname>expat</productname>
ne construit pas par défaut de bibliothèque : il faut utiliser
la ligne suivante :
<programlisting role="makefile">
<![CDATA[
libexpat.a: $(OBJS)
ar -rc $@ $(OBJS)
ranlib $@
]]>
</programlisting>
Un paquet RPM source de expat est disponible sur
<link xlink:href="&url.expat.rpm;">&url.expat.rpm;</link>.
</para>
</section>
&reference.xml.configure;
<section xml:id="xml.configuration">
&reftitle.runtime;
&no.config;
</section>
<section xml:id="xml.resources">
&reftitle.resources;
<section xml:id="xml.resources.xml">
<title><literal>xml</literal></title>
<para>
La ressource <literal>xml</literal> est retournée par
<function>xml_parser_create</function> et
<function>xml_parser_create_ns</function>, et représente
un analyseur XML à utiliser avec les autres fonctions de cette
extension.
</para>
</section>
</section>
&reference.xml.constants;
<section xml:id="xml.eventhandlers">
<title>gestionnaires d'événements</title>
<para>
Les gestionnaires d'événements XML sont :
<table>
<title>Les gestionnaires d'événements XML supportés</title>
<tgroup cols="2">
<thead>
<row>
<entry>Fonction &php; de configuration du gestionnaire</entry>
<entry>Description de l'événement</entry>
</row>
</thead>
<tbody>
<row>
<entry><function>xml_set_element_handler</function></entry>
<entry>
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.
</entry>
</row>
<row>
<entry>
<function>xml_set_character_data_handler</function>
</entry>
<entry>
"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.
</entry>
</row>
<row>
<entry>
<function>xml_set_processing_instruction_handler</function>
</entry>
<entry>
Les programmeurs &php; sont habitués aux instructions
exécutables (processing instructions ou PIs).
&lt;?php ?&gt; est une instruction exécutable où
<replaceable>php</replaceable> est appelé programme cible.
Ces instructions sont gérées de manière spécifique,
(sauf le programme cible "XML" qui est réservé).
</entry>
</row>
<row>
<entry><function>xml_set_default_handler</function></entry>
<entry>
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.
</entry>
</row>
<row>
<entry>
<function>xml_set_unparsed_entity_decl_handler</function>
</entry>
<entry>
Ce gestionnaire est appelé pour gérer les
déclaration des entités non analysées (NDATA).
</entry>
</row>
<row>
<entry>
<function>xml_set_notation_decl_handler</function>
</entry>
<entry>
Ce gestionnaire est appelé pour déclarer les notations.
</entry>
</row>
<row>
<entry>
<function>xml_set_external_entity_ref_handler</function>
</entry>
<entry>
Ce gestionnaire est appelé lorsque l'analyseur XML trouve une
référence à une entité générale externe. Cela peut être une
référence à un fichier ou à une URL. Reportez-vous à
<link linkend="example.xml-external-entity">entité externe</link>
pour un exemple.
</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section xml:id="xml.case-folding">
<title>Problèmes de casse</title>
<para>
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.
</para>
<para>
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
<function>xml_parser_get_option</function> et
<function>xml_parser_set_option</function>.
</para>
</section>
<section xml:id="xml.error-codes">
<title>Codes d'erreurs</title>
<para>
Les constantes suivantes sont définies comme des codes
d'erreurs XML : (retournées par <function>xml_parse</function>)
<simplelist>
<member>XML_ERROR_NONE</member>
<member>XML_ERROR_NO_MEMORY</member>
<member>XML_ERROR_SYNTAX</member>
<member>XML_ERROR_NO_ELEMENTS</member>
<member>XML_ERROR_INVALID_TOKEN</member>
<member>XML_ERROR_UNCLOSED_TOKEN</member>
<member>XML_ERROR_PARTIAL_CHAR</member>
<member>XML_ERROR_TAG_MISMATCH</member>
<member>XML_ERROR_DUPLICATE_ATTRIBUTE</member>
<member>XML_ERROR_JUNK_AFTER_DOC_ELEMENT</member>
<member>XML_ERROR_PARAM_ENTITY_REF</member>
<member>XML_ERROR_UNDEFINED_ENTITY</member>
<member>XML_ERROR_RECURSIVE_ENTITY_REF</member>
<member>XML_ERROR_ASYNC_ENTITY</member>
<member>XML_ERROR_BAD_CHAR_REF</member>
<member>XML_ERROR_BINARY_ENTITY_REF</member>
<member>XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF</member>
<member>XML_ERROR_MISPLACED_XML_PI</member>
<member>XML_ERROR_UNKNOWN_ENCODING</member>
<member>XML_ERROR_INCORRECT_ENCODING</member>
<member>XML_ERROR_UNCLOSED_CDATA_SECTION</member>
<member>XML_ERROR_EXTERNAL_ENTITY_HANDLING</member>
</simplelist>
</para>
</section>
<section xml:id="xml.encoding">
<title>Codage des caractères</title>
<para>
L'extension XML de &php; supporte les caractères
<link xlink:href="&url.unicode;">Unicode</link> grâce à
différents codages. Il y a deux types de codages de
caractères : le <glossterm>codage à la source</glossterm> et le
<glossterm>codage à la cible</glossterm>. &php; utilise le
<literal>UTF-8</literal> comme représentation interne.
</para>
<para>
L'encodage à la source est effectué lors de
<link linkend="function.xml-parse">l'analyse</link> du fichier par XML.
Lors de la <link linkend="function.xml-parser-create">création
d'un analyseur XML</link>), 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 :
<literal>ISO-8859-1</literal>, <literal>US-ASCII</literal> et
<literal>UTF-8</literal>. Les deux derniers sont des codages
à un seul octet, c'est-à-dire que les caractères
sont représentés sur un seul octet. <literal>UTF-8</literal>
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 &php;
<literal>ISO-8859-1</literal>.
</para>
<para>
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.
</para>
<para>
Si l'analyseur XML rencontre un caractère qu'il ne
connaît pas (hors limite, par exemple), il retournera une erreur.
</para>
<para>
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).
</para>
</section>
<section xml:id="xml.examples">
&reftitle.examples;
<para>
Voici quelques exemples de code &php; analysant un document XML.
</para>
<section xml:id="example.xml-structure">
<title>Exemple de structure XML</title>
<para>
Ce premier exemple affiche la structure de l'élément
de début dans un document avec indentation.
<example>
<title>Afficher une structure XML</title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
</section>
<section xml:id="example.xml-map-tags">
<title>Transtypage XML -> HTML</title>
<para>
<example>
<title>Transtypage XML -> HTML</title>
<para>
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.
</para>
<para>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</para>
</example>
</para>
</section>
<section xml:id="example.xml-external-entity">
<title>Entité externe</title>
<para>
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).
</para>
<para>
Le document XML qui est utilisé dans cet exemple est fourni plus
loin dans l'exemple (<filename>xmltest.xml</filename> et
<filename>xmltest2.xml</filename>).
</para>
<para>
<example>
<title>Entité externe</title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>xmltest.xml</title>
<programlisting role="xml">
<![CDATA[
<?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 xml: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>
]]>
</programlisting>
</example>
</para>
<para>
Ce fichier est inclus depuis <filename>xmltest.xml</filename>:
<example>
<title>xmltest2.xml</title>
<programlisting role="xml">
<![CDATA[
<?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>
]]>
</programlisting>
</example>
</para>
</section>
</section>
</partintro>
&reference.xml.entities.functions;
</reference>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->