REMARQUE ! Les informations sur cette page sont largement obsolètes. Pour obtenir des informations à jour sur le projet Mozilla, consulter la page de la communauté Mozilla francophone, leur blog principal et leur blog technique.
Pendant que l'adoption du XHTML continue de s'étendre aux cercles du développement web, la question inévitable se pose : ne pouvons-nous vraiment pas nous passer du désagréable HTML spécifique au navigateur et créer nos documents en pur XML ?
XML dans le navigateur a été le sujet de beaucoup de discussions animées au sujet du développement web avant-gardiste. Certains estiment que le remplacement de HTML par XML ne peut recuillir une audience importante en raison d'un manque d'agents utilisateurs pouvant correctement l'analyser et l'afficher. D'autres estiment que XML est vraiment approprié au serveur ou s'utilise seulement comme une structure descriptive de données et n'a aucune place dans le monde visuel du Web qui est déjà bien déservi par le HTML.
Malgré cela, la nouvelle génération de navigateurs possède de puissantes capacités XML. Les récentes versions de Mozilla offrent un analyseur syntaxique (ou parseur) et un moteur de rendu qui supportent les technologies XML comme les feuilles de style XML, les espaces de noms XML, XLink, SVG et MathML. Avec son support natif de SOAP et les prochaines implémentations de WSDL et de XSLT, Mozilla est assuré de devenir un puissant lecteur parmi les logiciels clients XML.
Mozilla permet aussi d'avoir un rendu du XML dans le navigateur avec CSS et de le manipuler avec le DOM. C'est un réel avantage pour tout ceux d'entre nous désirant expérimenter des transformations XML (à la fois visuelles et structurelles) sans devoir fouiller dans des technologies peu familières comme XPath, le langage naturel de XSLT pour parcourir le DOM. Si vous êtes déjà familier avec les CSS et le DOM, vous êtes plus qu'à mi-chemin de la réalisation de transformations XML dans Mozilla.
Cet article montre clairement la façon d'afficher du XML dans le navigateur avec un minimum de CSS et de JavaScript. Les exemples suivant ont été écrits et testés avec Mozilla 1.0 sur Linux Mandrake 9.0, Mac OS X et Win2K. Cet article n'est pas une initiation complète sur le DOM, CSS, ou XML et une compréhension de base de chacune de ces technologies est souhaitable.
J'ai choisi un fichier RSS épuré pour fournir un exemple XML à cet article. J'aurais pu choisir n'importe quel document XML au hasard, mais RSS est utilisé dans l'objectif particulier de la syndication de contenu, souvent des nouvelles et des articles de journaux Web (weblog) et est idéal pour démontrer les bases des transformations avec les CSS et le DOM. Tout au long de cet article, je montrerai comment utiliser les CSS pour appliquer un style de mise en forme aux éléments RSS et comment utiliser l'interface du DOM de niveau 2 pour parcourir et transformer le résultat. A la fin de cet article, je créerai (une esquisse évidemment ) un lecteur de RSS basé sur le navigateur alimenté lui même pas des RSS.
La première chose a faire est mettre en forme les éléments XML existants avec CSS. Comme avec le HTML, c'est accompli avec un lien sur une feuille de style.
Une feuille de style XML est généralement importée via une instruction
de traitement xml-stylesheet
dans l'en-tête du
document XML. C'est analogue à l'utilisation de la balise
link
en HTML pour importer une CSS et la syntaxe est
semblable :
<?xml version="1.0"?> <?xml-stylesheet href="rss.css" type="text/css"?>
À la différence du HTML, aucune supposition n'est faite sur le formatage
des éléments XML de la part du processeur. Un navigateur comprend
(implicitement ou autrement) qu'un élément <P>
HTML est un objet de mise en forme de type en bloc, tandis que <EM>
est un
objet de mise en forme de type en ligne. De même, un navigateur peut supposer sans risque
que l'écriture en gras est le formatage par défaut d'un texte à l'intérieur
d'un élément HTML <strong>
. Ce n'est pas ainsi avec du XML brut,
en le reliant à un un document CSS, les règles de base pour la mise en forme visuelle
de chaque élément et son contenu peuvent être données au processeur.
Je dois d'abord décider quels éléments sont à formater comme des éléments
de bloc. Puisque tous les éléments sont affichés par défaut sur une seule
ligne, j'ai seulement besoin d'indiquer les éléments de bloc dans la feuille de style.
Je commencerai en définissant l'affichage, la police et les propriétés des
cadres des éléments rss
, channel
et
item
:
rss { display:block; margin:10px; } channel { display:block; height:300px; width:280px; border:1px solid #000; overflow:auto; background-color:#eee; font: 12px verdana; } item { display: block; padding:10px; margin-bottom:10px; border-top:1px solid #ccc; border-bottom:1px solid #ccc; background-color:#fff; }
A ce point, je ne suis pas vraiment intéressé par certains éléments de
la métadonnée channel
, donc j'utiliserai display:none
pour
les supprimer de la sortie visuelle. Notez que cela n'enlève pas les
éléments du document; si j'avais voulu le faire, j'aurai utilisé la méthode du
DOM appropriée pour les enlèver par programmation. J'y arriverai un peu
plus tard. Je veux garder les éléments du channel title
et description
, donc je ferai mon CSS ainsi :
channel>title, channel>description { display: block; margin-left:10px; margin-top:10px; background-color:#eee; font-weight:bold; } channel>title { font-size:16px; } channel>description { font-size:10px; margin-bottom:10px; } item>title { font-weight:bold; } item>link, channel>link, channel>language { display: none; }
Pour vérifier mon style de mise en page, je démarre Mozilla 1.0 et lui donne mon document RSS. Voici le résultat jusqu'ici :
Comme vous pouvez le voir, mettre en page du XML avec une CSS est aussi
simple que de faire la même chose en HTML. Mais j'ai un problème :
Aucun de mes liens ne sont de vrais liens. C'est-à-dire qu'ils ne se
comportent pas comme des liens HTML quand je clique dessus. Je dois
trouver une façon de transformer les éléments link
de RSS
en des liens opérationnels. CSS est mal assorti pour fournir cette sorte de
fonctionnalité, mais j'ai un autre outil à ma disposition : DOM.
Si vous êtes déjà familier avec l'utilisation de l'interface du DOM de niveau 2 pour manipuler le HTML, la partie suivante doit vous être familière. Voici l'approche de base :
title
et link
du document RSS.
<a>
) avec le titre et le
texte de l'URL indiquées.
title
par le lien HTML dans le
document.
Le code suivant utilise la méthode
getElementsByTagName
du DOM pour récupérer
un ensemble de références d'élément item
du document
XML. La boucle for
qui suit réitère sur l'ensemble et obtient
les références de chaque éléments title
et link
.
Finalement, le texte du titre et du lien sont d'abord extraits en faisant
référence au noeud de texte de chacun, puis à la propriété
nodeValue
du noeud :
var allItems = document.getElementsByTagName("item"); for (var i=0;i<allItems.length;i++) { var itemElm = allItems[i]; var titleElm = itemElm.getElementsByTagName("title").item(0); var titleText = titleElm.firstChild.nodeValue; var linkElm = itemElm.getElementsByTagName("link").item(0); var linkURL = linkElm.firstChild.nodeValue; }
Ceci fournit la partie nécessaire qui établit un lien HTML approprié de chaque item du RSS. Cependant, un peu code supplémentaire est nécessaire pour que tout fonctionne.
Le concept des espaces de noms XML est devenu une recommandation du W3C
en 1999. Ils existent pour permettre aux éléments XML de différents schémas
d'être mélangés sans entrer en conflit. Par exemple, XHTML a un élément
title
, tout comme RSS. Pour empêcher un analyseur
syntaxique XML de confondre les deux, un espace de noms est déclaré
dans l'élément racine du document XML. L'espace de nom se compose
d'un préfixe associé à une URI et est utilisé pour distinguer des
éléments et des attributs importés d'autres spécifications XML.
Les balises suivantes montrent comment importer un élément
XHTML img
dans un document RSS :
<?xml version="1.0"?> <rss version="0.91" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <channel> <title>scottandrew.com</title> <link>http://www.scottandrew.com</link> <xhtml:img src="/img/photo.jpg" alt="Handsome pic of Scott"/> ... </rss>
L'attribut xmlns
associe le préfixe de l'espace de nom
"xhtml" avec l'URI. De cette façon, un analyseur syntaxique XML est
averti que l'élément img
existe dans un espace de nom
à l'extérieur de celui par défaut. (bien sûr, il n'y a aucune
garantie, pour que l'analyseur syntaxique sache quoi faire avec img
,
puisque tous les analyseurs syntaxiques XML ne sont pas nécessairement
des navigateurs.)
En utilisant l'interface du DOM avec un document XHTML, il est supposé
que tous les nouveaux éléments créés par programmation avec
createElement
sont en fait des éléments XHTML. Les spec
du DOM de niveau 2 donnent une méthode distincte pour la création
d'éléments venant d'un espace de nom différent. La méthode
createElementNS
accepte deux arguments : une
chaîne faisant référence à l'URI de l'espace de nom et une chaîne
représentant l'élément à créer :
var xhtml = "http://www.w3.org/1999/xhtml"; var newLinkElm = document.createElementNS(xhtml,"a");
Puisque mon application est destinée à être lue par un navigateur,
je peux utiliser createElementNS
pour importer un
élément <a>
XHTML dans mon document RSS.
Avec l'information recueillie par l'opération DOM précédente, je peux
assigner un attribut href
au nouvel élément <a>
,
puis créer et insérer un nouveau noeud texte. Puisque
l'attribut href
, comme l'élément <a>
lui-même, est importé du XHTML, je dois utiliser la méthode
setAttributeNS
. Cette méthode fonctionne exactement
comme la méthode setAttribute
du DOM 2 et utilise un
argument supplémentaire déclarant l'espace de nom de l'attribut.
Finalement, je remplace l'élément TITLE
RSS de cette item
avec l'élément <a>
XHTML , en utilisant la méthode
replaceChild
du DOM 2 pour le faire. Mozilla doit
maintenant permettre au titre de l'item de se comporter comme un lien
XHTML. Voici le code complet de mon script parcourant les noeuds :
var xhtml = "http://www.w3.org/1999/xhtml"; var allItems = document.getElementsByTagName("item"); for (var i=0;i<allItems.length;i++) { var itemElm = allItems[i]; var titleElm = itemElm.getElementsByTagName("title").item(0); var titleText = titleElm.firstChild.nodeValue; var linkElm = itemElm.getElementsByTagName("link").item(0); var linkURL = linkElm.firstChild.nodeValue; var newLinkElm = document.createElementNS(xhtml,"a"); var txtNode = document.createTextNode(titleText); //newLinkElm.setAttributeNS(xhtml,"href",linkURL); // NDT : incorrect voir plus bas newLinkElm.setAttributeNS("","href",linkURL); newLinkElm.style.display = "block"; newLinkElm.appendChild(txtNode); itemElm.replaceChild(newLinkElm,titleElm); }
Pour implémenter ceci, je dois associer le script avec le document
RSS pour que ces transformations du DOM puissent avoir lieu
à l'exécution. Au moment où j'écris ces lignes, je n'ai pas pu trouver
une façon convenable pour associer un fichier de script externe avec
un document XML (à la différence des xml-stylesheet
,
il ne semble y avoir aucune instruction de traitement "xml-script"
équivalente et il semble douteux que le W3C aille dans ce sens).
Il n'y a aucune méthode "onload" d'un document RSS, donc je vais avoir
besoin d'un plan d'attaque différent.
En utilisant une déclaration d'espace de noms XML je peux importer un
élément XHTML script
et l'insérer comme le dernier élément
dans la racine du document RSS. Mettre l'appel du script
à la fin force le document à être chargé en mémoire avant que le
JavaScript ne soit exécuté :
<?xml version="1.0"?> <?xml-stylesheet href="rss.css" type="text/css"?> <rss version="0.91" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <channel> <title>scottandrew.com</title> <link>http://www.scottandrew.com</link> <description>DHTML, DOM and JavaScript News</description> <language>en-us</language> <!-- ITEM elements go here --> </channel> <xhtml:script type="text/javascript" src="rss.js" /> </rss>
Le chargement du fichier RSS dans Mozilla produit maintenant le résultat désiré : des titres qui soient des liens cliquables. Vous pouvez voir un exemple fonctionnant ici, bien que vous ayez besoin de Mozilla 1.0 ou une version supérieure pour pouvoir le tester.
NDT : L'exemple orginal
donné par Scott Andrew ne fonctionnait que dans
les navigateurs dérivés de la branche de Mozilla 1.0, comme Mozilla 1.0.2,
Netscape 7, Chimera 0.6, ... Mais les liens crées dynamiquement ne
fonctionnaient plus à partir de Mozilla 1.1, et le
bogue 184744
avait été ouvert sur bugzilla
laissant penser à une regression. Cependant d'après
Boris Zbarsky, l'instruction
newLinkElm.setAttributeNS(xhtml,"href",linkURL);
était incorrecte,
puisque l'attribut href
d'un élément <a>
XHTML doit être dans un espace de nom nul. L'exemple donné par
Scott Andrew fonctionne dans les navigateurs dérivés de la branche de Mozilla 1.0
pour la seule raison que la version 1.0 a un bogue dans le traitement
des attributs des espaces de nom. En remplaçant l'instruction précédente
par l'instruction newLinkElm.setAttributeNS("","href",linkURL);
,
l'exemple fonctionne bien dans Mozilla 1.0 et plus. (testé dans Mozilla 1.3b
sous Linux et Netscape 7.02 sous Mac OS 9).
Mozilla supporte les hyperliens de base via XLink comme alternative à l'importation XHTML. Avec XLink, il n'y a pas besoin de créer un nouvel élément. Au lieu de cela, la fonctionnalité d'hyperliens vient de l'attachement d'attributs XLink à l'élément en question, faisant ainsi de n'importe quel élément un lien potentiel.
Pour accomplir cela, fixez les attributs XLink appropriés à l'item de
l'élément title
avec la méthode
setAttributeNS
. Voici une version modifiée du JavaScript
qui incorpore XLink au lieu de XHTML :
var xlink = "http://www.w3.org/1999/xlink"; var allItems = document.getElementsByTagName("item"); for (var i=0;i<allItems.length;i++) { var itemElm = allItems[i]; var titleElm = itemElm.getElementsByTagName("title").item(0); var linkElm = itemElm.getElementsByTagName("link").item(0); var linkURL = linkElm.firstChild.nodeValue; titleElm.setAttributeNS(xlink,"type","simple"); titleElm.setAttributeNS(xlink,"show","replace"); titleElm.setAttributeNS(xlink,"href", linkURL); }
Il a été avancé qu'il serait préférable que les développeurs web continuent à faire du HTML valide 4.01 tant que les agents utilisateurs ne seront pas capables de faire une analyse et un rendu XML corrects. Peut-être. Cependant comme je l'ai démontré, quelques agents utilisateurs sont déjà bien préparés pour traiter le XML. Le puissance des CSS et du DOM dans les transformations XML a amené pour beaucoup la question de savoir si des technologies comme XSLT sont vraiment nécessaires. Je ne fais pas telles revendications, mais si les capacités de Mozilla 1.0 sont un signe, l'avenir de XML sur le Web est accessible et s'annonce bien sans aucun doute.
(Site mise à jour le mardi 16 mars 2004)