documents

XHTML — Mythes et réalités

Il est difficile aujourd'hui de trouver un langage de développement web aussi incompris que XHTML. Dans cet article, nous en examinerons les raisons, démêlerons quelques concepts souvent confus pour les auteurs et ferons des suggestions pratiques pour une utilisation réelle de XHTML.

Cet article s'adresse non seulement aux développeurs qui utilisent XHTML pour la première fois mais aussi aux auteurs et créateurs de contenus qui veulent en savoir plus sur les langages de balisage extensibles.

Sommaire

  1. Introduction
  2. Le but de XHTML
  3. XHTML et le type de contenu
  4. XHTML strictement
  5. Absence de support
  6. Négociation de contenu
  7. Recommandations
  8. Références
  9. À propos du document

Introduction

La première version informelle du langage HTML parue en 1992 le décrivait comme un « langage de balisage hypertexte[1] et un « format SGML ». SGML, un métalangage puissant pour créer des langages de balisage, a été développé entre 1969 et 1980[2], mais il y avait déjà des travaux remontant à 1945[3].

Langage puissant et pratiquement adaptable à l'infini, SGML a été largement adopté, en particulier par l'industrie de la haute technologie, l'administration et l'université[4], et a donné lieu à un grand nombre d'applications. C'était un choix logique pour créer le langage de balisage du World Wide Web — mais il était aussi trop compliqué pour l'auteur occasionnel. Pour faciliter l'utilisation de HTML, on rogna les encoignures si bien que certains disent qu'il ne remplit pas les conditions pour prétendre au titre d'application SGML[5].

Lorsque le W3C décida de créer le langage XML en 1996, les justifications en étaient que « l'objectif est de pouvoir servir, recevoir et traiter du SGML générique sur le Web comme c'est maintenant possible avec HTML. Pour cette raison, XML est conçu pour être mis en œuvre facilement et pour être interopérable à la fois avec SGML et HTML[6] ». Plus loin, on l'y décrit comme « un dialecte de SGML extrêmement simple ».

Puisque les buts de conception de XML lui-même reflétaient en partie ceux du langage HTML original, il était logique que les travaux commencent par formuler un langage de balisage fondé sur XML. Le langage XHTML 1.0[7] devint une recommandation du W3C en janvier 2000, suivi de la version XHTML 1.1[8] en mai 2001. En septembre 2008, les travaux sur XHTML 2.0[9] se poursuivent. Un autre projet court au sein du groupe de travail XHTML[10] en vue de produire une version 1.2, avec des fonctionnalités telles que ARIA[11], les rôles[12], le module ACCESS[13] et RDFa[14].

De ce qui précède et pour faire court, on notera avec intérêt que XML est toujours du SGML. La FAQ SGML[15] de David Megginson le justifie ainsi : « Contrairement à HTML, XML n'est pas une application SGML ; il s'agit plutôt d'un ensemble de conventions simples pour utiliser SGML sans certaines caractéristiques plus ésotériques ».

En bref…
La famille de langages XHTML est créée et suivie par le groupe de travail XHTML du W3C, la version actuelle étant la version 1.1. Une révision 1.2 et une nouvelle version 2.0 sont en préparation.

Le but de XHTML

En ce qui concerne le langage XHTML, son existence tient à deux raisons. La première est de mouvoir le langage de balisage du Web de SGML vers XML et, par la même occasion, de nettoyer complètement les restes des saletés qui ont pollué le Web pendant beaucoup d'années. La série des versions 1.* de XHTML représente seulement la première étape de ce processus.

La deuxième raison, probablement la plus importante, est d'ajouter la capacité XML d'étendre le langage au travers d'espaces de noms. Elle permet à l'auteur d'exprimer plus de structures et une sémantique plus riche qu'il n'est aujourd'hui possible avec HTML. En effet, XHTML hérite de la possibilité de gérer plusieurs langages — au lieu d'étendre HTML de façon monolithique, on peut étendre XHML au travers de modules, chaque module définissant un sous-ensemble propre du langage.

En théorie, cela signifie que l'extension du langage peut avoir lieu sans qu'il faille mettre à jour le navigateur.

En pratique, il est relativement facile de créer un navigateur capable d'analyser des documents XML même à plusieurs espaces de noms, de leur appliquer des règles CSS et d'utiliser un script JavaScript sur l'arbre des nœuds pour manipuler les choses qui en résultent. Il est beaucoup plus compliqué de construire le navigateur de façon à ce qu'il puisse présenter le sens des structures, indépendamment de la méthode réellement impliquée. Cela va bien au-delà de ce qu'on peut obtenir avec des bouts de JavaScript qui ajoutent des comportements aux éléments : malgré les meilleures volontés des auteurs de pages, la sémantique des éléments doit être communiquée au navigateur pour qu'il puisse adapter la présentation, visuelle, sonore ou tactile, aux besoins de l'utilisateur.

Avec HTML, on y parvient assez facilement aujourd'hui. Un navigateur « sait » ce que la balise <h1> est censée signifier et il peut présenter le contenu du titre d'une façon qui ait un sens pour l'utilisateur, que ce soit en le prononçant plus fort, en l'affichant dans une fonte, dans une graisse et une couleur particulières à l'écran, ou en levant un ensemble de points distinct sur une bande en braille.

Dans un document XML mélangeant des espaces de noms, à l'inverse, la présence d'une balise inconnue, disons <foo:bar>, n'aura aucun sens pour le navigateur, et il ne pourra donc pas déterminer quelle forme de présentation est appropriée pour communiquer le sens de l'élément. Des études sont menées, notamment par l'activité Web sémantique[16] du W3C, pour trouver une solution à ce problème.

Il est bien sûr possible d'écrire un navigateur qui comprenne plusieurs langages de balisage et donc laisse aux auteurs beaucoup plus de latitude dans l'utilisation des éléments pour exprimer les concepts et les idées. Ainsi un navigateur fondé sur XML peut à la fois analyser du XML générique et « connaître » des langages spécifiques tels que XHTML, MathML et SVG.

D'autres pièges existent si on veut utiliser XHTML sur le Web, comme nous le verrons, mais la famille de langages est aussi utilisable pour des besoins de stockage d'informations dans d'autres contextes, où elles seront traitées par des outils plus spécialisés.

En bref…
XHTML est conçu pour faciliter l'emploi de langages fondés sur XML dans les applications de l'utilisateur final telles que les navigateurs, mais on peut aussi l'utiliser pour divers besoins de stockage et traitement des données dans les situations où le Web n'est qu'un canal parmi d'autres. XHTML tire avantage de l'extensibilité de XML pour gérer plusieurs espaces de noms et, au travers d'eux, plusieurs langages.

XHTML et le type de contenu

Lors de la transmission d'un contenu du serveur web au navigateur web au moyen de HTTP, il existe un mécanisme pour identifier le type des données, à savoir l'en-tête Content–Type[17]. En lisant cette en-tête, le navigateur détermine rapidement comment traiter le contenu reçu — le rendre, le traiter d'une certaine manière ou encore présenter une invite de téléchargement.

Les valeurs de l'en-tête HTTP Content-Type sont des Types de média Internet[18], dûment enregistrés auprès de l'IANA (Internet Assigned Number Authority)[19]. En utilisant ce registre, les fabricants de navigateur peuvent ajouter plus facilement une gestion des types de média et être raisonnablement sûrs de la compatibilité avec les autres navigateurs.

Pour indiquer à un navigateur qu'il s'agit bien de traiter du XHTML, il faudrait paramétrer le bon type de contenu. Sachez que les navigateurs capables de manipuler du XML, à l'heure actuelle, ont deux analyseurs — l'un pour XML et l'autre pour HTML. Le navigateur se sert du type de média pour décider lequel des deux utiliser.

Un aspect important de la spécification HTTP est que l'en-tête Content–Type envoyée par le serveur est prioritaire[20], c'est-à-dire qu'elle écrasera des constructions telles que celle-ci :

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

Pour XHTML, le type de contenu approprié est application/xhtml+xml. Le navigateur considère toutes les données de ce type comme étant du XML, en particulier du XHTML, et les traite conformément aux règles XML — mais seulement si le navigateur est capable d'analyser du XML au premier chef et de « comprendre » le XHTML. Tous n'en sont pas capables.

Afin que les auteurs puissent commencer à utiliser XHTML, goûter les règles modifiées et explorer les possibilités du nouveau langage — et néanmoins utiliser le balisage dans les navigateurs existants, on décida d'autoriser l'emploi du type de contenu text/html.

Cela entraîne plusieurs conséquences : non-détection des erreurs de bonne conformation (well-formedness), observation des règles HTML d'application des styles et d'utilisation du DOM, et mélange des espaces de noms ; c'est-à-dire qu'il n'est pas faisable, par exemple, d'avoir un document XHTML contenant du MathML ou un langage pareillement fondé sur XML sans utiliser les méthodes spécifiques du navigateur pour manipuler le balisage « étranger » incorporé au HTML.

Lorsque l'on utilise des règles de syntaxe XHTML dans un agent utilisateur HTML, il est fortement recommandé de suivre les consignes de compatibilité[21] décrites dans la spécification XHTML afin d'éviter toutes mauvaises surprises. La plupart des navigateurs manipulent le XHTML comme encore une autre forme de soupe de balises HTML (HTML tagsoup), et cela ne devrait donc pas représenter un gros problème.

En bref…
Les navigateurs se servent de l'en-tête HTTP Content-Type, qui est prioritaire, pour déterminer le type du contenu reçu. C'est la valeur de cette en-tête qui décide de l'utilisation de l'analyseur HTML ou XML sur les données. Vous pouvez mettre sur le XHTML, même dans sa version 1.1, une étiquette text/html, si vous acceptez que la page soit traitée comme du HTML et non comme du XHTML.

XHTML strictement

L'idée selon laquelle XHTML est « plus strict » que HTML naît du fait que les documents écrits en XHTML, en tant qu'application de XML, sont soumis aux règles de traitement XML, en particulier la gestion des « erreurs fatales ».

Lorsqu'un processeur XML conforme détecte une erreur fatale, il ne doit pas, dans la terminologie normalisée, poursuivre normalement le traitement, c'est-à-dire qu'il y a interdiction absolue de récupérer de l'erreur si une infraction à la bonne conformation est détectée.

Plusieurs erreurs sont considérées comme fatales : la violation de la contrainte de bonne conformation[22] est la plus connue. Il existe d'autres erreurs fatales liées à la manipulation des entités. Elles ne sont pas abordées dans le cadre de cet article.

Ce n'est pas une erreur fatale que d'enfreindre les contraintes de validité, la gestion des erreurs de syntaxe autres que celles impliquant la bonne conformation est donc indulgente, et ces erreurs devraient simplement être signalées à l'utilisateur à la demande.

Il existe une autre différence majeure entre HTML fondé sur SGML et XHTML fondé sur XML : dans une définition DTD SGML, il est possible de spécifier si l'apparition de tel élément est interdite au sein de tel autre — illustration avec la définition des éléments P et FORM ci-dessous :

<!ELEMENT P — O (%inline;)*                  -- paragraphe -->
<!ELEMENT FORM — - (%block;|SCRIPT)+ -(FORM) -- formulaire interactif -->

En langage courant, pour que le document soit valide, un élément P ne peut pas contenir autres choses que des éléments imbriqués (inline elements), et un élément FORM ne peut pas contenir un autre FORM. Une telle prohibition est impossible en XML, et des règles à propos de quel élément peut y entrer doivent être spécifiées ensuite dans la prose[23], ce qui rend les situations telles que la suivante indétectables pour les validateurs formels comme pour les processeurs XML :

<form action="x">
 <div>
  <form action="y">
   <fieldset>
     <legend>z</legend>
   </fieldset>
  </form>
 </div>
</form>

La construction ci-dessus mettrait un validateur HTML dans tous ses états, tandis qu'un analyseur XML, même validant, ne cillerait pas. À noter toutefois que l'on peut implémenter des contraintes telles que décrites ci-dessus en XML Schema[24].

Inversement, HTML autorise certaines constructions et XHTML non, comme omettre les balises fermantes sur certains éléments non vides, ainsi que sur les éléments vides, ce qui invaliderait par exemple :

<p>voici un paragraphe.<p>voici un autre paragraphe.
<br><hr>

Quoiqu'il en soit, cette forme de balisage n'est pas bâclée, la définition DTD HTML 4.01 la décrit de manière plutôt précise selon les règles permises par SGML, et on ne peut pas à ce titre la juger comme « moins stricte ». En outre, HTML ne permet pas l'imbrication incorrecte des éléments et rend obligatoire la présence d'une déclaration DOCTYPE.

Sachant cela, nous pouvons conclure, malgré l'obligation de s'interrompre des processeurs XML pour des erreurs fatales, que l'on ne peut pas définir formellement toutes les infractions à la syntaxe en XHTML tandis que c'est possible en HTML, qu'un document HTML est, strictement parlant, un document HTML seulement s'il est complètement valide[25] et que les documents XML peuvent tout-à-fait avoir une syntaxe invalide et pourtant rester des documents XML.

La chose importante à noter pour les auteurs est que c'est l'application de traitement qui est plus ou moins stricte, pas le langage même — et qu'un document XHTML sera traité par un processeur XML conforme seulement s'il est envoyé avec le type de contenu approprié.

En bref…
Envoyé avec le type de contenu text/html, votre document XHTML ne sera pas soumis aux règles de traitement XML décrites ci-dessus, et le navigateur ne le traitera pas différemment que s'il s'agissait de HTML.

Absence de support

L'absence de support de XHTML est la réalité du Web en 2008. Dans les versions de Firefox précédant la série 3.0, le processeur XHTML dans Gecko était si mauvais que les propres ingénieurs de Mozilla le déconseillaient[26] ; aucune version d'Internet Explorer jusqu'à IE 8 inclus ne supporte XHTML, et nombre d'autres navigateurs tels que Lynx n'ont jamais été écrits au départ pour manipuler du XML.

Beaucoup d'autres agents utilisateurs, tels que les moteurs de recherche[27], sont dans le même cas : aucun support de XML ni de XHTML.

Entre parenthèses, on peut duper Internet Explorer en réalité, au moins jusqu'à la version 7, pour traiter du XHTML envoyé avec le type application/xhtml+xml. La ruse est de profiter de ce que Microsoft appelle le « reniflage du type MIME »[28], ce qui pour faire court signifie qu'IE passera outre l'en-tête de type de contenu dans certaines circonstances, telles que par exemple si l'adresse URI contient le suffixe .html. On peut en avoir un exemple en visitant la page http://www.w3.org/International/tests/sec-ruby-markup-1.html, qui malgré l'apparence HTML induite par le suffixe dans l'adresse URI, est servie avec le type application/xhtml+xml (au 2 octobre 2008) et devrait donc produire une invite de téléchargement dans les versions standards d'IE.

Toujours est-il qu'au final le résultat sera le même. C'est l'analyseur de soupe de balises HTML dans Internet Explorer qui traitera le balisage, ce qui ne laisse pas de s'interroger, en tous cas l'auteur, sur le pourquoi d'un tel exercice.

Bien que ce ne soit pas recommandé, on peut aussi envoyer les documents XHTML avec le type application/xml ou bien text/xml, mais tandis que les navigateurs équipés pour XML mais pas pour XHTML pourront analyser réellement le document et même, dans une certaine mesure, le styler, les constructions telles que la suivante ne fonctionneront pas :

<a href="URI">link text</a>

Il ne suffit pas au navigateur de simplement analyser un langage fondé sur XML pour « comprendre » que l'élément A représente un hyperlien. On peut y pallier en partie avec le module XLink[29] qui fournit plusieurs attributs tels que xlink:href. En indiquant au navigateur que la valeur de cet attribut devrait être traitée comme étant l'adresse URI dans un hyperlien, même des langages génériques fondés sur XML peuvent recevoir des équivalents de l'élément A donné — à condition bien sûr que le langage fondé sur XML utilise le module XLink.

En bref…
Pour assurer une gestion du plus grand nombre possible de navigateurs et d'autres agents utilisateurs tels que les moteurs de recherche, vous devriez considérer une utilisation de HTML 4.01 en tant que text/html ou une négociation de contenu pour servir soit du HTML, soit du XHTML selon ce qui convient.

Négociation de contenu

Que le serveur web négocie avec l'agent utilisateur pour déterminer quelle réponse conviendra le mieux à l'utilisateur, l'idée n'est pas nouvelle. Introduite dans HTTP 1.1 dès 1999, elle est malheureusement sous-employée. Cette partie de l'article se concentrera sur la négociation de contenu sur le serveur via l'en-tête de requête HTTP Accept.

En théorie, négocier pour du HTML ou du XHTML est assez simple : regarder l'en-tête HTTP Accept, déterminer lequel de text/html et application/xhtml+xml a la priorité la plus élevée, envoyer le document dans le bon langage de balisage, en le transformant si une version n'existe pas déjà en cache.

En pratique, c'est devenu beaucoup plus compliqué à cause des navigateurs Internet Explorer qui, sur plusieurs générations, incluent à la chaîne Accept le fragment "*/*", annonçant par-là gérer absolument tout. Le soin d'en démontrer l'absurdité patente est laissé au lecteur.

Heureusement, on peut ne pas tenir compte du "*/*", et après examen approfondi, il est clair que la spécification HTTP n'interdit pas explicitement un tel comportement ni déclare de façon autoritaire quoi faire dans une telle situation. Par conséquent, nous serons pragmatiques et oublierons la prétention d'IE. L'algorithme suivant, décrit en Perl, analyse les en-têtes HTTP Accept et renvoie soit "xhtml", soit "html", selon celui estimé le meilleur.

Voici une approche pragmatique pour résoudre l'équation « HTML ou XHTML ? », qui ne fonctionnera pas comme un analyseur d'en-tête Accept générique.

sub examineAccept {
 my $accept = shift() ;
 $accept =~ s#(\n|\r)##g ;

               #  -------------------------------------------- — #
               # — C'est la valeur de conservation par défaut. — #
               #  -------------------------------------------- — #
                #
 my $contentType = 'text/html' ;

               #  -------------------------------------------- — #
               # — Si, à ce stade, aucun XHTML n'est mentionné — #
               # — explicitement, on retourne 'html',          — #
               # — et vice versa.                              — #
               #  -------------------------------------------- — #
                #
 return('html') if ( $accept !~ m#\Qapplication/xhtml+xml\E#i ) ;
 return('xhtml') if ( $accept !~ m#\Qtext/html\E#i ) ;

               #  -------------------------------------------- — #
               # — On récupère explicitement les paramètres q  — #
               # — de text/html et application/xhtml+xml       — #
               #  -------------------------------------------- — #
                #
 my($html_quality) = $accept =~ m#text/html(?:;\s*q\s*=\s*([0-9\.]+))?# ;
 if ( $html_quality eq '' ) {
  $html_quality = '1.0' ;
 }

 my($xhtml_quality) = $accept =~ m#application/xhtml+xml(?:;\s*q\s*=\s*([0-9\.]+))?# ;
 if ( $xhtml_quality eq '' ) {
  $xhtml_quality = '1.0' ;
 }

               #  -------------------------------------------- — #
               # — S'ils sont de poid égal, on retourne        — #
               # — la valeur par défaut.                       — #
               #  -------------------------------------------- — #
                #
 if ( $html_quality == $xhtml_quality ) {
  return($contentType) ;
 }

               #  -------------------------------------------- — #
               # — Si le paramètre q de text/html est plus     — #
               # — lourd, retourner 'html'                     — #
               #  -------------------------------------------- — #
                #
 if ( $html_quality > $xhtml_quality ) {
  return('html') ;
 }

               #  -------------------------------------------- — #
               # — Et vice versa.               — #
               #  -------------------------------------------- — #
                #
 if ( $html_quality < $xhtml_quality ) {
  return('xhtml') ;
 }

               #  -------------------------------------------- — #
               # — Si, pour une raison insondable, on arrive   — #
               # — ici, on retourne la valeur par défaut.      — #
               #  -------------------------------------------- — #
                #
 return($contentType) ;
}

Une fois que l'on a déterminé quel langage de balisage annoncer, on doit effectuer une transformation correcte du contenu. Il ne suffit pas de remplacer le type de contenu et la déclaration DOCTYPE — il faut changer la syntaxe XHTML en HTML. Par chance, c'est une petite tâche à condition de n'avoir pas utilisé de caractéristiques spéciales de XHTML — telles qu'un mélange d'espaces de noms — ni de structures étendues de XHTML 1.1 telles que Ruby, ou de XHTML 1.2 telles que ARIA ou ACCESS.

Pour le cas élémentaire, on doit seulement remplacer toutes les occurrences de "/>" par ">", tous les selected="selected" par selected, et tous les checked="checked" par checked.

Pour les cas plus complexes, on devra remplacer les nouvelles structures par des structures HTML équivalentes — ce qui est souvent difficile puisqu'il n'existe aucune gestion Ruby ou ACCESS dans HTML — ou les ignorer, en perdant ainsi de la structure et de la sémantique.

Quel que soit le cas, il est recommandé d'utiliser des transformations XSLT et de mettre en cache les versions séparées de façon à ne pas trop nuire au temps de traitement. Les remplacements simples décrits ici constituent en général une solution fragile.

En bref…
La négociation de contenu peut représenter une méthode pratique pour servir du HTML ou du XHTML, en fonction de ce que demande l'agent utilisateur, qui repose toutefois sur l'ignorance de la valeur spéciale "*/*".

Recommandations

Information

L'auteur est membre du groupe de travail XHTML du World Wide Web Consortium. Cet article n'est endossé ni par le W3C, ni le groupe de travail, quoique l'expérience et les connaissances acquises à leur contact transparaissent dans la rédaction.

Références

  1. HyperText Mark–up Language
    Berners–Lee, Tim, novembre 1992
  2. A Brief History of the Development of SGML
    SGML User’s Group, juin 1990
  3. As We May Think
    Bush, Vannevar, juillet 1945
  4. Cover Pages Technology Reports
    Cover, Robin, juillet 2002
  5. Dropping the Normative Reference to SGML
    Ray, Arjun, octobre 1999
  6. Extensible Markup Language
    Bray, Tim; Sperberg–McQueen, C. M., novembre 1996
  7. XHTML 1.0
    Pemberton, Steven et al, janvier 2000
  8. XHTML 1.1
    McCarron, Shane; Masayasu Ishikawa, février 2007
  9. XHTML 2.0
    Axelsson, Jonny et al, juillet 2006
  10. XHTML 2 WG
    W3C, septembre 2008
  11. Accessible Rich Internet Applications (WAI-ARIA) Version 1.0
    W3C, août 2008
  12. XHTML Role Attribute Module
    W3C, octobre 2007
  13. XHTML ACCESS Module
    W3C, mai 2008
  14. RDFa in XHTML: Syntax and Processing
    W3C, septembre 2008
  15. David Megginson’s SGML FAQ
    Megginson, David, septembre 1998
  16. W3C Semantic Web Activity
    Berners–Lee, Sir Tim, et al, juillet 2008
  17. Content–Type in HTTP 1.1
    Fielding, R, et al, juin 1999
  18. RFC 1590 — Media Type Registration Procedure
    Postel, J, novembre 1996
  19. Assigned Numbers (STD 2, RFC 1700)
    Reynolds, J., Postel, J., octobre 1994
  20. Authoritative Metadata
    Fielding, Roy T. et al, avril 2006
  21. C. HTML Compatibility Guidelines
    Pemberton, Steven et all, janvier 2000
  22. well–formedness constraint in XML 1.0, 4th edition
    Bray, Tim et al, septembre 2006
  23. 4.9 SGML Exclusions in XHTML 1.0
    Pemberton, Steven, août 2002
  24. XML Schema Part 1: Structures Second Edition
    W3C, octobre 2004
  25. HTML 4.01: Conformance
    Ragget, Dave; Le Hors, Arnaud; Jacobs, Ian, décembre 1999
  26. Mozilla Web Developer FAQ:
    Sivonen, Henri, mai 2007
  27. XHTML in Search Engines
    Dorward, David, février 2008
  28. IE content–type logic
    Gupta, Vishu, février 2005

À propos du document

Première publication :
3 octobre 2008
Dernière mise à jour :
6 octobre 2008
Niveau requis :
Connaissance de HTML
Auteur :
Tina Holmboe
Suivi par :
Tina Holmboe
© 2008 yoyodesign.org - Certains droits réservés