Aller au menu - Aller au contenu

Icône L'implementation DOM

Mise à jour : 07/12/2010
Difficulté : Intermédiaire Intermédiaire
5 975 visites depuis 7 jours , dont 157 sur ce chapitre , classé 32/777
Chapitre rédigé par Thunderseb

Compatibilité de la méthode
Image utilisateur
Méthode
Image utilisateur
Internet Explorer
Image utilisateur
Firefox
Image utilisateur
Opera
Image utilisateur
Google Chrome
Image utilisateur
Safari
DOMImplementation
Oui
avec ActiveX
Oui
Oui
Non
Non

Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

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).

Mozilla et le W3C parlent de l'interface DOMImplementation et Microsoft parle de l'objet implementation. J'ai une préférence pour l'appellation objet, ça semble moins barbare et c'est plus conventionnel.


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 :

Code : JavaScript
1
if (document.implementation) { }


Il vaut mieux tester également la prise en charge de la méthode createDocument :

Code : JavaScript
1
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 :

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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.

Attention que Webkit, le moteur de rendu utilisé notamment dans Safari et Google Chrome ne gère pas la méthode load de DOMImplementation. Il n'est donc pas possible de l'utiliser pour charger des données XML.

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 :

Code : XML
1
2
3
4
5
6
<?xml version="1.0" encoding="iso-8859-1"?>
<topic>
	<author>Thunderseb</author>
	<country>Belgium</country>
	<lang>French</lang>
</topic>


Pour plus de lisibilité et de facilité, j'ai mis la fonction DOMImplementation créée ci-dessus dans le fichier oDOMImplementation.js.


Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!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>


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 :

Code : HTML
1
<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 :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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>";
 
?>


Il ne faut surtout pas oublier de bien définir le type de contenu comme étant du text/xml. De plus, votre XML généré doit être valide, sinon vous aurez des problèmes lors du chargement du fichier par l'objet DOMImplementation.

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 :

Code : XML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?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 :

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<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 :

Code : JavaScript
1
2
3
4
5
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 :

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.

Code : HTML
1
<input type="button" value="Afficher les BD de cette série" onclick="displayBD();" />


Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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 ^^

Si vous avez usage de ce script, pour pouvez évidemment le complexifier en insérant des données en plus dans le XML comme les auteurs, si la série est finie (et complète ou non), le type de BD que c'est (cartonnée souple (les premières BD, ça vaut de l'argent) ou cartonnée rigide)...

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


Chapitre précédent Sommaire Chapitre suivant

Partager

10 commentaires pour "L'implementation DOM"
Note moyenne : 3.61 / 4 (137 votes)
Pseudo Commentaire
Hors ligne softdounia # Posté le 10/07/2009 à 00:49:17
A
Avatar

Ville : Alger
Pays : Algérie
Études : USTHB

:waw:
Attention que Webkit, le moteur de rendu utilisé notamment dans Safari et Google Chrome ne gère pas la méthode load de DOMImplementation. Il n'est donc pas possible de l'utiliser pour charger des données XML.
:colere:

Les 40e rugissants et les 50e hurlants. o_O --> Brainstorming --> CamelCase
Image utilisateur

-------------
"je crois qu'on ne peut mieux vivre qu'en chercant à devenir meilleur, ni plus agréablement qu'en ayant pleine conscience de son amélioration"
Socrate >_<
-------------
les meilleurs peintres se sont fait dire qu’ils n’étaient pas bon, aujourd’hui ce sont des Dieux!
-------------
RTFM :-° l'expression anglaise d'argot Internet Read the fucking manual (« Lis le foutu manuel ») ;
-------------
Mon CV en ligne ici
 
Hors ligne Nesquik69 # Posté le 10/07/2009 à 10:30:35
Slave of the Rythm
Avatar
Groupe : Auteurs

Ville : Tassin la demi-lune
Pays : France métropolitaine

Faut te calmer bilred. D'accord, c'est dommage que Webkit ne gère pas cela mais t'as pas besoin de faire un message inutile pour exprimer ta colère.
 
Hors ligne SoftDeath # Posté le 21/08/2009 à 18:32:01
ben...euh...j'sais plus :s
Avatar

Ville : Toulouse
Pays : France métropolitaine
Études : Université Paul Sabatier Toulouse

Jolie tutoriel, mais assez complexe !
Hors ligne marcel35 # Posté le 09/04/2010 à 15:18:47

Non supporté par safari et google chrome ? C'est dommage ça effectivement.
Hors ligne Claros # Posté le 26/10/2010 à 10:09:34
Combien ai-je d'avatar ?
Avatar

Juste deux petites questions, est-il possible d'afficher une barre de chargement avec l'implémentation DOM comme pour le XHR ? Ainsi que le temps de chargement ? (j'ai vu qu'on pouvait le voir avec la console d'erreur).

Merci.

The cake is a lie !
 

Voir tous les commentaires