Méthode |
Internet Explorer |
Firefox |
Opera |
Google Chrome |
Safari |
---|---|---|---|---|---|
DOMImplementation |
Oui |
Oui |
Oui |
Non |
Non |
L'object XMLHttpRequest est pratique pour récupérer un peu n'importe quoi comme type de données (text, XML, HTML...), mais est généralement un peu lourd à utiliser. Si vous désirez juste récupérer une source de données au format XML, vous pouvez le faire via DOMImplementation.
L'interface DOMImplementation fait partie du DOM Level 2 Core et est supportée par la plupart des navigateurs. Internet Explorer supporte le DOMImplementation, mais par le biais d'un contrôle ActiveX (comme les versions 5 et 6 d'IE avec XMLHttpRequest).
En réalité IE gère le DOMImplementation, mais pas complètement. Il ne gère que la méthode hasFeature (du DOM Level 1) et pas createDocument dont nous allons nous servir. Donc pour savoir comment réagir en fonction du navigateur, il n'est pas bien malin de faire un test de gestion de l'objet implementation :
if (document.implementation) { }
Il vaut mieux tester également la prise en charge de la méthode createDocument :
if (document.implementation && document.implementation.createDocument) { }
Nous allons créer une fonction générique qui ira récupérer une source XML à l'adresse sUrl, et qui renverra le contenu dans une fonction de callback fCallback. Ainsi nous disposerons d'une fonction qui ne s'occupera que de la gestion de DOMImplementation :
function getDOMImplementation(sUrl, fCallback) {
var dom;
if (window.ActiveXObject) {
dom = new ActiveXObject("Microsoft.XMLDOM");
dom.onreadystatechange = function() {
if(dom.readyState == 4) {
fCallback(dom);
}
};
}
else if (document.implementation && document.implementation.createDocument) {
dom = document.implementation.createDocument("", "", null);
dom.onload = function() {
fCallback(dom);
}
}
else {
alert("Votre navigateur ne gère pas l'importation de fichiers XML");
return;
}
dom.load(sUrl);
}
L'ActiveX XMLDOM permettant à IE de gérer l'importation DOM fonctionne exactement comme un ActiveX XMLHTTP. Ainsi, si vous le voulez, vous pouvez contrôler le bon fonctionnement des opérations avec onreadyonchange.
L'objet implementation requiert donc la méthode createDocument qui permet de créer un document XML. Les deux premiers arguments sont le namespace et le nom qualifié du document XML. Le troisième argument est le doctype. Laissez les deux premiers vides, et le troisième nul.
Voici donc un récapitulatif, qui charge un fichier XML et en lit une entrée. Le fichier XML est simpliste, en voici son contenu :
<?xml version="1.0" encoding="iso-8859-1"?>
Thunderseb
Belgium
French
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
xmlns="http://www.w3.org/1999/xhtml"
http-equiv="Content-Type" content="text/html; charset=iso-8859-1"
href="mep.css" rel="stylesheet" type="text/css" media="all"
Techniques AJAX - DOMImplementation - XML Statique
type="text/javascript" src="oDOMImplementation.js"
type="text/javascript"
<!--
function getData(oData) {
var author = oData.getElementsByTagName('author')[0].firstChild.data;
var country = oData.getElementsByTagName('country')[0].firstChild.data;
var lang = oData.getElementsByTagName('lang')[0].firstChild.data;
alert(author + ' - ' + country + ' - ' + lang);
}
//-->
Techniques AJAX - DOMImplementation - XML Statique
type="button" value="Récupérer les données" onclick="getDOMImplementation('DOMImplementation_1.xml', getData);"
Et donc, lorsque vous cliquez sur "Récupérer les données", cela affichera :
Vous pouvez utiliser une page PHP pour générer un fichier XML. Dans ce cas, des variables GET peuvent être transmises à la page PHP via l'url. Voici un exemple qui charge du XML créé dynamiquement au moyen d'une page PHP.
La page HTML est rigoureusement la même que dans l'exemple ci-dessus, à l'exception de l'appel de la fonction :
type="button" value="Récupérer les données" onclick="getDOMImplementation('DOMImplementation_2.php?Pseudo=Thunderseb', getData);"
La page PHP (DOMImplementation_2.php) contient ce code :
<?php
header("Content-Type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>";
echo "<topic>";
if (isset($_GET['Pseudo'])) {
$pseudo = $_GET['Pseudo'];
if ($pseudo == 'Thunderseb') {
echo '<author>Thunderseb</author>';
echo '<country>Belgium</country>';
echo '<lang>French</lang>';
} else if ($pseudo == 'Laurence') {
echo '<author>Laurence</author>';
echo '<country>Belgium</country>';
echo '<lang>French</lang>';
}
}
echo "</topic>";
?>
Pour ne pas rester que sur de la théorie et des exemples limités, je vous propose ici de réaliser une petite base de données (un fichier XML) laquelle est lue par un script Javascript. L'idée de l'exemple est de tenir une liste de toutes mes BD (Bandes Dessinées) et d'afficher, via une liste déroulante, les différents albums d'une série (tous les albums de la BD Pierre Tombal par exemple).
Tout d'abord, voici la structure XML que j'utilise pour ma liste de BD :
<?xml version="1.0" encoding="utf-8"?>
<!-- PIERRE TOMBAL -->
name="Pierre Tombal"
num="4" title="des os pilants"
num="5" title="ô suaires"
num="12" title="la pelle aux morts"
num="21" title="k.os"
num="22" title="ne jouez pas avec la Mort !"
num="24" title="on s'éclate mortels !"
<!-- LES PROFS -->
name="Les Profs"
num="2" title="loto et colles"
num="3" title="tohu-bahut"
num="4" title="rentrée des artistes"
num="5" title="chute des cours"
num="9" title="rythme scolaire"
<!-- et ça continue, encore et encore, c'est que le début, d'accord d'accord... -->
Les BD sont donc classées par série (exemple : Pierre Tombal) qui contient la liste des albums (exemple : album numéro 5 ayant comme titre ô suaire).
L'idée est de récupérer le contenu XML, via DOMImplementation, et de lister toutes les séries, et les afficher dans une liste déroulante. A partir de cette liste, l'utilisateur choisit une série et clique sur un bouton pour afficher les albums de cette série. Voici comment se présente le HTML, tout simple :
Sélection de la série
id="bdForm" method="get" action=""
for="serieName"Choisir une série :
<!-- On écrira le SELECT dans le SPAN ci-dessous -->
id="outputListDiv"Liste des séries non chargée...
type="button" value="Afficher les BD de cette série" onclick="displayBD();"
id="outputBDFieldset"
BD en ma possession
<!-- On écrira la TABLE avec la liste des albums dans le DIV ci-dessous -->
id="outputBDDiv"
Voici le début du script :
var DOMXML = null;
window.onload = function() {
DOMImplementation('data.xml', getData);
}
DOMXML sera une variable globale dans laquelle on mettra la structure XML, de manière à l'exploiter par après. La fonction init est appelée lors du chargement (onload) et se charge de lire le fichier XML et d'appeler la fonction de callback getData.
Maintenant, getData :
function getData(oData) {
DOMXML = oData;
var series = oData.getElementsByTagName("serie");
var sorted = [];
// Classement par ordre alphabétique, via tableau à 2 dimensions
for (var i=0, c=series.length; i<c; i++) {
sorted.push([series[i].getAttribute("name"), i]);
}
sorted.sort();
// Génération du SELECT
var list = "<select name=\"serieName\" id=\"serieName\">\n";
for (var i=0, c=sorted.length; i<c; i++) {
list += "<option value=\"" + sorted[i][1] + "\">" + sorted[i][0] + "</option>\n";
}
list += "</select>\n";
document.getElementById("outputListDiv").innerHTML = list;
}
On commence par récupérer tous les éléments
<serie>
, et pour chaque élément, on récupère le nom de la
série ainsi que l'indice de parcourt (i) que l'ont met dans un tableau, lequel tableau est
ajouté dans le tableau sorted.
L'utilité de ça est d'appliquer un
sort
sur le tableau sorted pour ainsi trier
les sous-tableaux par ordre alphabétique. Une fois que c'est fait, on reboucle pour créer le
<select>
que l'on ajoute dans la page.
Avec ça, on récupère les séries et on affiche le
<select>
. Maintenant, quand l'utilisateur clique sur un
bouton, on affiche la liste des albums contenus dans la série sélectionnée.
type="button" value="Afficher les BD de cette série" onclick="displayBD();"
function displayBD() {
// récup' de l'id de la série, écrit dans la VALUE de l'OPTION
with (document.getElementById("serieName")) var idSerie = parseInt(options[selectedIndex].value);
var serie = DOMXML.getElementsByTagName("serie")[idSerie];
var bds = serie.getElementsByTagName("bd");
// Création de la TABLE avec les résultats
var table = "<table class=\"sortable\" width=\"100%\">\n";
table += "<tr><th width=\"20\">N°</th><th>Titre de l'album</th></td>\n";
for (var i=0, c=bds.length; i<c; i++) {
table += "<tr><td>" + bds[i].getAttribute("num") + "</td><td>" + bds[i].getAttribute("title") + "</td></tr>\n";
}
table += "</table>\n";
document.getElementById("outputBDDiv").innerHTML = table;
}
Comme on a sauvé les données XML dans la variable globale DOMXML, on s'en sert pour récupérer les albums (variable bds) de la série donnée. L'affichage via un tableau HTML est plus pratique d'une liste ordonnée, puisque rien ne garantit que la numérotation des BD se suit, et toutes les BD ne possèdent pas le même type de numérotation (par exemples les ré-éditions au format A4 des premiers albums de Gaston Lagaffe sont numérotées R1, R2, R3, R4 et R5).
Vous pouvez tester le code en action ici , et parcourir ma collection de BD
DOMImplementation est pour moi la solution la plus pratique si vous voulez charger du contenu XML. Il est fait pour ça, et il serait dommage de ne pas l'utiliser.
Plus facile à mettre en place que XMLHttpRequest
Adapté pour le XML
Non supporté par Safari et Google Chrome
Seulement des requêtes GET