L'implementation DOM

Image utilisateur Image utilisateur

Méthode

Image utilisateur Image utilisateur

Internet Explorer

Image utilisateur Image utilisateur

Firefox

Image utilisateur Image utilisateur

Opera

Image utilisateur Image utilisateur

Google Chrome

Image utilisateur Image utilisateur

Safari

DOMImplementation

Oui
avec ActiveX

Oui

Oui

Non

Non

Introduction

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) { }

Utilisation

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.

Avec du XML statique

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"?>
<topic>
<author>Thunderseb</author>
<country>Belgium</country>
<lang>French</lang>
</topic>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="mep.css" rel="stylesheet" type="text/css" media="all" />
<title>Techniques AJAX - DOMImplementation - XML Statique</title>
<script type="text/javascript" src="oDOMImplementation.js"></script>
<script 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);
}
//-->
</script>
</head>
<body>
<h1>Techniques AJAX - DOMImplementation - XML Statique </h1>
<p>
<input type="button" value="Récupérer les données" onclick="getDOMImplementation('DOMImplementation_1.xml', getData);" />
</p>
</body>
</html>

Test du code

Et donc, lorsque vous cliquez sur "Récupérer les données", cela affichera :

Image utilisateur

Avec du XML dynamique

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 :

<input 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>";
?>

Test du code

Exemple pratique, gestion de BD

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"?>
<bds>
<!-- PIERRE TOMBAL -->
<serie name="Pierre Tombal">
<bd num="4" title="des os pilants" />
<bd num="5" title="ô suaires" />
<bd num="12" title="la pelle aux morts" />
<bd num="21" title="k.os" />
<bd num="22" title="ne jouez pas avec la Mort !" />
<bd num="24" title="on s'éclate mortels !" />
</serie>
<!-- LES PROFS -->
<serie name="Les Profs">
<bd num="2" title="loto et colles" />
<bd num="3" title="tohu-bahut" />
<bd num="4" title="rentrée des artistes" />
<bd num="5" title="chute des cours" />
<bd num="9" title="rythme scolaire" />
</serie>
<!-- et ça continue, encore et encore, c'est que le début, d'accord d'accord... -->
</bds>

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 :

<fieldset>
<legend>Sélection de la série</legend>
<form id="bdForm" method="get" action="">
<div>
<label for="serieName">Choisir une série : </label>
<!-- On écrira le SELECT dans le SPAN ci-dessous -->
<span id="outputListDiv"><em>Liste des séries non chargée...</em></span>
</div>
<p><input type="button" value="Afficher les BD de cette série" onclick="displayBD();" /></p>
</form>
</fieldset>
<fieldset id="outputBDFieldset">
<legend>BD en ma possession</legend>
<!-- On écrira la TABLE avec la liste des albums dans le DIV ci-dessous -->
<div id="outputBDDiv"></div>
</fieldset>

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.

<input 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 ^^

Conclusion

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.

Points forts

  • Plus facile à mettre en place que XMLHttpRequest

  • Adapté pour le XML

Points faibles

  • Non supporté par Safari et Google Chrome

  • Seulement des requêtes GET