Bien souvent lorsque nous devons utiliser XML dans nos applications, qu'il s'agisse d'un fichier de configuration ou d'échanges de données, nous commençons dans un premier temps par utiliser un fichier XML fait main et écrit directement depuis un éditeur de code.
Cette solution intermédiaire nous permet de brosser rapidement le tableau et mettre en place les premières briques de l'application.
Par contre, une fois l'application prototypée nous allons devoir utiliser un middleware pour prendre en charge la génération automatique de ce fichier.
En fonction du système d'information utilisé et de l'environnement de travail dans lequel nous opérons, nous allons avoir recours à diverses technologies. Au cours de cette étape, nous utiliserons le binome PHP / MySQL afin de générer notre arborescence XML.
Deux approches, DOMXML (ou DOM) ou directement écrire dans le texte
Si vous utilisez PHP 4, il est possible d'avoir recours aux fonctions DOMXML et si vous utilisez PHP 5 vous vous orienterez plutôt du coté de DOM. Ces outils permettent de travailler et de directement manipuler la structure de fichiers XML.
Si cette approche à le mérite d'être très souple, adaptée et élégante, il reste cependant toujours possible de générer du contenu XML à la mode texte... donc en écrivant directement du XML sous sa forme littérale. Quelle que soit la méthode utilisée et en fonction des contextes, toutes conviennent, par contre, pour la suite de cet article, nous travaillons en mode litéral et donnerons la correspondance en PHP5.
De manière courte, générer un arbre XML reste une opération on ne peut plus simple. Il suffit, soit d'instancier un objet donnant accès au DOM (PHP 4 et PHP 5), soit de déclarer le prologue XML (mode littéral).
Puis, soit en ajoutant des noeuds par les fonctions adaptées (PHP 4 et PHP 5), soit en concatenant des bouts de chaines de caractères (mode littéral), de construire une à une l'intégralité des branches.
Dans les exemples ci-dessous, nous pouvons voir comment le fragment de code suivant est mis en place en fonction des trois solutions retenues, à savoir PHP 4, PHP 5 et Mode texte :
Code XML souhaité
<?xml version="1.0" encoding="utf-8"?>
<items>contenu de la balise</items>
Génération en PHP4
<?php
$xml = new domxml_new_doc('1.0');
$tag = $xml->create_element('items');
$text = $xml->create_text_node('contenu de la balise');
$tag->append_child($text);
$xml->append_child($tag);
echo $xml->dump_mem( true, 'UTF-8' );
?>
Génération en PHP 5
<?php
$xml = new DOMDocument('1.0', 'utf-8');
$tag = $xml->createElement('items','contenu de la balise');
$xml->appendChild($tag);
echo $xml->saveXML();
?>
Génération en mode littéral
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<items>';
$xml .= 'contenu de la balise';
$xml .= '</items>';
echo $xml;
?>
Certes, le code est généré et correspond à notre attente, mais n'oublions pas que ce code intervient sur une réponse client serveur et va donc être renvoyé au demandeur. Il faut donc s'assurer que celui-ci soit donc livré dans un format adéquat et interprétable en tant que tel par le receveur.
Dans ce but nous allons regarder du coté du type MIME.
Type MIME du fichier
Le type mime permettant de renseigner sur la nature d'un document, nous devons nous assurer que le fichier XML renvoyé par le fichier PHP possède bien un type mime adéquat pour un arbre XML. L'un, php,étant de type application/x-httpd-php et l'autre, xml, de type application/xml ou text/xml.Nous devons donc ajouter l'une ou l'autre des instructions PHP suivantes pour modifier l'entête du fichier et s'assurer de bien retourner une arborescence XML,
header('Content-Type: text/xml');
header('Content-Type: application/xml');
Pour en savoir plus sur les types mimes employés par les fichiers rapprochez vous l'article relativement complet : les types MIME par SelfHTML.
Formatage et encodage du fichier
De même, il est important de s'assurer que les caractères particuliers, tels que les caractères accentués, glyffes, et autres caractères spéciaux soient bien interprétés. Ainsi, il est préférable d'utiliser un encodage de caractères qui soit suffisament large comme l'UTF-8.
Il ne suffit pas d'encoder seulement le fichier PHP qui génère l'arbre XML, mais également de veiller à ce que l'ensemble de la chaine, c'est à dire l'ensemble des fichiers utilisés tels que le fichier HTML, le code Javascript qui traitera l'information, les fichiers de connection à la base de données, la base de données elle même, l'interclassement MySQL.... bref, s'assurer que tous convergent vers ce standard.
Généralement les navigateurs interprètent les documents text/xml comme s'il s'agissait de documents application/xml, ce qui revient à rendre l'utilisation de l'un ou de l'autre fréquemment confondue.
Cependant, il faut prendre en considération que les documents text/xml ne prennent pas en compte le prologue <?xml version="1.0" encoding="UTF-8"?> et traitent le contenu comme s'il était encodé en US-ASCII, excepté si un entête HTTP le définit explicitement :
header('Content-type: text/html; charset=utf-8');
Attention, l'UTF-8 utilise, ou pas, une signature BOM (Bytes Order Mark) qui renforce la définition du type d'encodage utilisé. Bien que cette signature se veuille invisible pour la plupart des utilisateurs, elle peut apparaître dans certains affichages sous forme de trois caractères insignifiants .
Ces caractères viennent rendre inutilisable l'arborescence XML en créant une erreur, il faut donc retirer la signature utilisée pour l'encodage UTF-8.
NotePad++ permet de changer cette information depuis le menu Encodage > Convertir en UTF-8 (sans BOM), Dreamweaver permet également de le faire depuis le menu Modifier > Propriétés de la page onglet Titre / Codage.
Enfin, du fait que le fichier de connection à la base est souvent un fichier lié, il faut s'assurer que la connection et l'échange des informations sera bien maintenu en UTF-8. Pour cela, il est possible d'ajouter l'instruction suivante qui devrait garantir la bonne utilisation de l'encodage tout au long de la requête :
mysql_query("SET NAMES 'utf8'");
Vous pouvez vous rapprocher de l'article UTF-8 PHP MySQL (histoire d'encodage) pour creuser plus en avant le sujet de l'encodage et de l'échange de données client serveur basé sur PHP et MySQL.
Compléments d'entête
Afin de garantir une génération systématique du fichier XML à chaque requête et de ne pas piocher dans le cache, il peut être judicieux de compléter l'entête du fichier par deux déclarations.
La première Cache-Control devrait s'assurer de cela, et la seconde Expires (utilisant une date plus ancienne) venant renforcer le fait que le navigateur régénère le fichier et ne le pioche pas dans la cache, du fait même que la date de validité sera forcément dépassée.
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 10 Jul 1990 05:00:00 GMT");
Vous pouvez consulter d'autres entêtes du protocole HTTP si vous souhaitez affiner certains points de votre fichier.
Autres points à ne pas négliger
Il existe encore quelques points dont il faut s'assurer afin de ne pas engendrer d'erreur. Par exemple, si vous générez un fichier PHP depuis Dreamweaver, celui-ci fabrique à la base un document HTML, donc toutes les balises <html>, <head> et <body> sont présentes.
Il faut les retirer pour, d'une part, ne pas compromettre la bonne validité du document XML et d'autre part, ne pas charger l'arborescence de noeuds qui n'auraient rien à faire dans le fichier généré.
Sur ce même point, le document PHP doit non seulement commencer par une balise <?php et non uniquement <?, mais de plus, cette balise ne doit pas être précédée d'un quelconque espace, qu'il s'agisse de plusieurs retours chariot ou d'un simple espace.
Détails du code
Une fois l'ensemble de ces points vérifiés, il ne reste plus qu'à générer l'arborescence XML. Voici par exemple une approche qui peut être retenue d'une part, en mode litéral et d'autre part, en utilisant l'objet DOMDocument en PHP5.
Vous pouvez si vous le souhaitez , récupérer et installer les fichiers nécessaires. Il suffit alors de créer une base de données nommée php_xml et d'y injecter la requête SQL fournie.
Ensuite, en lançant le fichier php_xml_5.php, ou le fichier php_xml_literal.php, l'arbre XML sera obtenu en retour.
Le fichier de connection
<?php
$dbhost = 'localhost';
$dbname = 'php_xml';
$dbuser = 'root';
$dbpass = '';
$conn = mysql_pconnect($dbhost, $dbuser, $dbpass);
?>
Le fichier PHP qui génère l'arborescence XML en mode litéral
<?php
include_once("connect.php");
header('Content-Type: text/xml');
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 10 Jul 1990 05:00:00 GMT");
mysql_select_db($dbname, $conn);
mysql_query("SET NAMES 'utf8'");
$sql = "SELECT * FROM `departements`";
$items = mysql_query($sql);
$xml = '<?xml version="1.0" encoding="UTF-8"?>';
if (mysql_num_rows($items) != 0){
$xml .= '<items>';
while ($item = mysql_fetch_assoc($items)){
$xml .= '<item>';
foreach($item as $key => $value){
$xml .= '<'. $key . '>';
$xml .= $value ;
$xml .= '</'. $key . '>';
}
$xml .= '</item>';
}
$xml .= '</items>';
}
echo $xml;
?>
Et pour information, voici la version PHP5
<?php
include_once("connect.php");
mysql_select_db($dbname, $conn);
$sql = "SELECT * FROM `departements`";
$db_items = mysql_query($sql);
$xml = new DOMDocument('1.0', 'utf-8');
if (mysql_num_rows($db_items) != 0){
$items = $xml->createElement("items");
while ($db_item = mysql_fetch_assoc($db_items)){
$item = $xml->createElement("item");
foreach($db_item as $key => $value){
$node = $xml->createElement($key,$value);
$item->appendChild($node);
}
$items->appendChild($item);
}
$xml->appendChild($items);
}
echo $xml->saveXML();
?>






