Framework de présentation basé sur XML, XSL et .NET
e monde Java est (sur-)peuplé de frameworks de présentation, commerciaux ou
gratuits. En particulier, nous avons déjà eu l’occasion de survoler
Struts
(basé sur les patterns MVC, singleton, médiateur, commande et mémento) que nous
avions comparé à WebForms, framework intégré à la plate-forme .NET. A l’issue
de cette présentation comparée, nous avions évoqué la possibilité de mettre en
place un framework de présentation flexible et basé sur les langages
XML et
XSL.
C’est exactement l’objectif de cet article : essayer de bâtir avec vous, de manière progressive, un socle propre, évolutif et efficace de développement de sites Web. Nous procéderons par étapes, en nous attachant aux aspects incontournables d’un framework de présentation mais aussi en essayant d’apporter systématiquement une réponse cohérente en utilisant les technologies connexes à XML. Bien entendu, dans cette optique, nous justifierons nos éventuels « écarts de conduite ».
La motivation de cet article vient d’une conviction de l’auteur que l’utilisation intelligente de XML peut raccourcir considérablement les temps et les coûts de développement d’un site Web (mais tous les frameworks nous promettent déjà ce genre de choses) tout en améliorant la testabilité et la qualité de l'application. Le framework que nous allons élaborer ici n’existe pas, n’est pas à vendre, mais à construire. C’est un projet ambitieux, et nous invitons les lecteurs à donner leur avis et à partager leurs idées novatrices sur le site DotNetGuru au travers des commentaires et forums.
XML
XML est un langage textuel et arborescent permettant de décrire des données structurées. Le type d’informations que l’on décrit en XML va des images vectorielles en 2D (SVG) aux mondes virtuels 3D (X3D), en passant par les documents administratifs typiques tels que les bons de commande, factures, appels d’offres… Bref, XML nous offre un cadre, une syntaxe, pour bâtir de nouveaux langages. Il nous apporte également un outillage assez riche, à commencer par les outils de lecture/écriture de documents XML (parseurs), les outils de contraintes (schémas) et de transformation (XSL).
Dans cet article, nous allons créer quelques structures de données XML permettant de gérer présentation, internationalisation et personnalisation, et nous nous appuierons pour la partie visualisation sur des langages standards (également compatibles avec XML) tels que XHTML, XSLFO ou SVG.
Voici l’exemple sur lequel nous allons travailler: un système de recherche d’appartements à louer. La liste des appartements disponibles est décrite dans le document XML suivant :
<?xml
version="1.0"
encoding="iso-8859-1"
?>
<Appartements>
<Appartement
type="f3"
surface="60">
<Loyer
mensualité="750"
charges="50"
devise="EUROS"
/>
<Adresse
numéro="74"
voie="rue" nomDeVoie="Turenne"
ville="Paris"
pays="France"/>
<Description>
Petit appartement sympa
au 6ème étage
d'un immeuble de
standing. Proche
commerces et transports,
lumineux et agréable à vivre.
</Description>
</Appartement>
<Appartement
type="f2"
surface="43">
<!--
etc... -->
</Appartement>
</Appartements>
XML Schémas
Il existe de nombreux langages de contraintes permettant de fixer lexique et grammaire d’un langage basé sur XML, c’est-à-dire :
Nous
retiendrons ici XML Schéma car il est standard, puissant, et écrit
lui-même en XML. D’autant que l’outillage est aujourd’hui tout à fait adapté à
ce langage : VisualStudio.NET permet, d’un simple clic, de « générer
le XML Schéma » du document XML en cours d’édition. Le résultat est
assez convaincant, et disponible sous format textuel ou
graphique.
<?
xml version="1.0" ?>
XSL
XSL est une norme double qui décrit à la fois
Ce chapitre utilise XSLT pour transformer, trier, filtrer des informations métier décrites en XML, mais aussi pour effectuer la fusion (la jointure) de plusieurs documents XML (usage typique de XSLT pour l’internationalisation). XSLT est un véritable langage de programmation, particulièrement adapté au traitement de données arborescentes.
Voici un exemple (simpliste) de transformation du document XML précédent en une page HTML.
<?
xml version="1.0" encoding="iso-8859-1"?>
Pipeline de traitements
Une feuille de style est un organe de transformation qui travaille sur un (ou plusieurs) document XML en entrée et génère un (ou plusieurs) document en sortie. Si le document produit en sortie est un document XML bien formé, rien n’empêche de coupler la sortie d’une première feuille XSL à l’entrée d’une seconde… et ainsi de suite. On parle dès lors de pipeline de transformations. Cette technique est séduisante, car elle permet de bien répartir les responsabilités sur les différents étages du pipeline, au lieu de bâtir une feuille XSL qui traiterait à la fois de la présentation, de l’internationalisation, de la personnalisation, etc…
Comme nous l’avons mentionné plus haut, nous allons prendre l’exemple d’un site d’offres de locations d’appartements. L’utilisateur saisit dans un formulaire HTML les critères de sélection de sa recherche d’appartement, et le système sélectionne les offres correspondantes (dont la description est en XML bien entendu), puis les présente en HTML. Il serait également souhaitable que l’utilisateur membre authentifié du site puisse personnaliser sa page d’accueil, sa charte graphique, la disposition des différents éléments composant son interface graphique. Et, cela va sans dire, le site doit s’adapter aux préférences linguistiques de l’utilisateur.
Deux approches antithétiques
Il existe typiquement deux approches de la présentation de données : « push » et « pull ».
La plupart des frameworks Web tels que Apache Struts, Microsoft WebForms, PHP, adoptent une approche « pull » où les pages dynamiques doivent polluer leur code avec des instructions de code en Java, VB.NET ou C#, et PHP. Cette approche est simple, intuitive pour un développeur, mais rend difficile la création collégiale de pages Web par des développeurs ET des graphistes. Les efforts du type TagLibs et WebForms sont un élément de réponse, mais nécessitent toujours de comprendre un langage autre que HTML.
Autre technique, mise en œuvre par le framework XMLC de Enhydra, le « push ». Cette fois, les pages de présentation sont rédigées entièrement dans le langage que maîtrisent les graphistes : HTML. Ce n’est que plus tard que les pages seront traitées : lors de l’exécution d’une requête, XMLC permet au développeur Java de charger la page HTML sous la forme d’un graphe d’objets Java en mémoire, et de modifier ce modèle en ajoutant aux bons endroits les informations dynamiques. L’identification des zones « à remplacer » est triviale, elle s’appuie sur un attribut « id » que l’on place sur les éléments HTML.
Nous choisissons ici la deuxième approche, en utilisant XSL en lieu et place du Framework XMLC. Cette façon de faire nous paraît à la fois la plus propre et la plus respectueuse de la philosophie de XML : la séparation entre contenu et présentation.
Framework de présentation en XSL
Nous souhaitons présenter en HTML la liste des offres de location d’appartement correspondant à une requête particulière. Le premier réflexe consiste à séparer l’exécution de la requête et la présentation de son résultat dans deux feuilles de style différentes. Dans cette section, nous allons nous focaliser sur la deuxième feuille, qui se charge exclusivement de la présentation.
L’idée est de rédiger un document XHTML en utilisant l’outil graphique (WYSIWYG) de conception de pages Web de VisualStudio.NET. Cette page Web modèle (« template ») ne s’attache pas du tout aux données contenues mais décrit précisément l’apparence souhaitée ; elle représente le canevas graphique que l’on devra suivre pour présenter le résultat de la requête de l’utilisateur.

Pour simuler notre outil de présentation, supposons que le résultat de la requête de l’utilisateur soit le même que le premier exemple de document XML donné en introduction de cet article :
<?
xml version="1.0" encoding="iso-8859-1" ?>
Il nous suffit alors de fusionner les données (XML) et leur template de présentation (XHTML) en utilisant une feuille de styles XSL.

<?
xml version="1.0" encoding="iso-8859-1"?>
Quelques
explications s’imposent toutefois : la feuille de style précédente copie à
l’identique la plupart des éléments du modèle XHTML (attributs compris), à
l’exception de la balise TABLE, dont on ne conserve que les attributs et la
première ligne. Les lignes suivantes du tableau sont générées dynamiquement, en
itérant sur la liste des offres de location (stockées dans le fichier
file:///D:/DotNetGuru/XML-Framework/appart.xml'). Notez
que cette approche fonctionne bien pour les cas très simples ; un cas réel
utiliserait un modèle beaucoup plus complexe comportant plusieurs tableaux,
et notre feuille de style ne conviendrait plus. Il faudrait, dans ce cas,
associer un identifiant unique à chaque zone dynamique (en utilisant l’attribut
ID des éléments XHTML par exemple) ; la feuille de style XSL s’attacherait
à remplacer toutes les zones dynamiques par des données métier présentées en
HTML. De
même que pour la partie présentation, l’internationalisation peut être gérée
par l’insertion dans une page Web de l’appel à un composant de traduction
automatique de mots-clé abstraits en leur traduction dans la langue préférée de
l’utilisateur courant (le header HTTP accept-langage nous informe de cette
préférence). Même remarque que précédemment, cela vient polluer le code HTML de
la page de présentation, et rend les choses plus complexes pour les graphistes
qui ne disposent pas nécessairement de l’environnement d’exécution des pages
dynamiques (éviter que chaque designer ait à développer ses pages et les tester au
sein d’un serveur d’application…). De plus, ajouter des balises spécifiques
rend difficile l’utilisation de certains outils graphiques de génération de
pages Web. L’alternative
est la même que pour la présentation : au lieu de tirer l’information
traduite dans la page Web, poussons-là grâce à une nouvelle feuille de style
XSL. Mais cette fois-ci, il nous faudra un peu d’aide de la part des graphistes
qui bâtissent les modèles HTML : notre feuille XSL
d’internationalisation devra déterminer quelles zones sont à traduire, et à
quel message abstrait l'application fait référence. Plusieurs techniques s’offrent à nous,
par exemple :
L’exemple
ci-dessus est partiel, bien entendu : il faudrait que notre feuille de
style prenne en paramètre la langue préférée de l’utilisateur, et qu’elle
recherche la traduction des mots-clés dans le fichier XML adéquat. Une
remarque toutefois concernant ces techniques : cela suffit à traduire le
texte dans la langue préférée de l’utilisateur, mais en aucun cas à prendre en
considération les problématiques culturelles : il faut également adapter
les couleurs du site, les sons joués… qui peuvent avoir des sémantiques variées
selon les pays. D’autre
part, nous avons parlé de traduction de texte vers des langues
« proches » du français (au sens de l’écriture). Ces techniques sont
inefficaces lorsque les langues cibles sont plus éloignées. L’arabe et le
chinois sont de bons exemples, puisque leur sens ou direction d’écriture ne sont
pas les mêmes qu’en français, ce qui implique généralement une re-conception
complète de l’interface utilisateur. C’est
le premier besoin auquel doit répondre un framework : être aisément
adaptable aux souhaits des concepteurs de sites. Il faut typiquement que la
mise en page, la charte graphique, l’agencement des éléments les uns par
rapport aux autres… soient faciles à modifier. La
tendance actuelle pour maximiser la liberté des concepteurs est de rendre
chaque partie du site modulaire : si chaque élément d’information est
indépendant des autres, rien n’empêche de choisir les éléments à la carte, et
de les organiser à notre guise. C’est typiquement ce que l’on retrouve dans un
« portail » : chaque élément d’information est généré par une
« portlet », que l’on peut activer ou désactiver à souhait. XSL
est l’outil idéal pour réaliser la fusion (ou l’agrégation) d’un ensemble de
documents XHTML. Prenons l’exemple d’une feuille de styles qui organise dans un
tableau un ensemble de pages atomiques (nos équivalents de
« portlets ») :
Modifier
l’agencement des portlets dans l’agrégat final revient dès lors à modifier le
« portail XSL ». Cette approche est sensée pour
celui qui connaît déjà la
syntaxe XSL, mais gagnerait à être rendue descriptive. On peut tout à fait
imaginer un document XML dans lequel on décrirait de manière abstraite
l’agencement des portlets, et le « portail XSL » ne ferait que suivre
les directives de ce fichier XML de configuration. Cela permettrait du même
coup à l’utilisateur final de sélectionner lui-même (comme dans la plupart des
portails) les composants qui l’intéresse. Enfin,
toujours concernant le paramétrage, mentionnons le fait que l’utilisation de
XSL n’exclut absolument pas l’emploi simultané de feuilles de style
CSS. Rien
n’empêche en effet d’associer une feuille CSS à l’agrégat XHTML de manière à
redéfinir globalement sa charte graphique. Les amateurs de chartes génériques
et évolutives pourront également imaginer comment générer des feuilles de
styles CSS dynamiquement en XSL… Enfin,
le risque de notre approche est que chaque portlet soit considérée comme un
composant atomique, dont nous ne pouvons personnaliser la présentation. En réalité,
XSL nous offre la même flexibilité que les langages de programmation Orientés
Objet : il est tout à fait possible d’hériter d’une feuille de
style XSL,
de redéfinir certaines règles tout en conservant les autres intactes. La
feuille fille peut bien entendu, lors de la redéfinition d’une règle, invoquer
la règle équivalente de la feuille mère (l’équivalent du super() de java, ou du
base() de C#). Jusqu’à
présent, toutes les données dont nous avons parlé étaient à
priori stockées
dans des documents textuels XML. Rien n’empêche de charger ces informations
depuis une base de données relationnelle, un annuaire LDAP (DSML aidant), ou
tout autre type de source d’informations. Le
framework .NET nous facilite énormément la tâche sur cet aspect. Il permet de
configurer : La
bonne nouvelle pour nous qui souhaitons obtenir des données au format XML est
qu’un DataSet a deux facettes : certes, il peut charger ses données depuis
n’importe quelle source (dont les bases de données relationnelles), mais il
maintient également une représentation XML des informations ainsi
chargées ! La structure d’un DataSet (qui peut contenir un ensemble de
tables, colonnes et relations) est d’ailleurs décrite en XMLSchéma. La
démarche du développement de l’accès aux données est donc la suivante. Il faut
tout d’abord, dans VisualStudio.NET, configurer la connexion à la source de
données grâce à l’outil « Server explorer », ce qui se fait en deux
étapes : Puis
nous ajoutons un DataSet au projet courant. Ceci nous amène à un environnement de
conception d’une structure de données, sur lequel il suffit de glisser-déposer
la table « Offres » de notre base de données. Immédiatement, VS.NET
modifie le schéma du DataSet de manière à ce qu’il reflète la structure de la
table Offres. Notez que le schéma d’un DataSet est manipulable graphiquement
dans VS.NET, et qu’il est sauvegardé au format XMLSchéma : 
Internationalisation (i18n)

Customiser le framework de présentation

Accès aux sources de données
Le DataSet doit être « chargé » à partir d’une source de données. Dans le cas d’une base de données relationnelle, il faut s’appuyer sur un objet de type « DataAdapter » qui déclenche une requête SQL sur la base de données, et copie les enregistrements résultants dans notre DataSet. Il suffit donc dans VS.NET de créer (graphiquement bien sûr) un DataAdapter en précisant :

Pour se faire une idée, voici les lignes de code C# générées par VS.NET et permettant de charger notre DataSet à partir de MSAccess :
(...)
oleDbConnection1 =
Une fois le DataSet chargé, il nous faut récupérer ses données au format XML et leur appliquer une transformation ne pose aucun problème :
XPathDocument doc =
new XpathDocument(new StringReader(données.GetXml()));Travailler sur des documents XML convient tout à fait en phase de mise au point du framework de présentation : il s’agit d’une sorte de bouchon (propre). Et comme nous venons de le voir, réaliser l’intégration du framework de présentation avec d’autres sources de données est assez simple (surtout si l’on s’appuie sur l’outillage fourni par VisualStudio.NET).
Bref rappel du mode de validation
d’Apache Struts
Dans le monde Java, de nombreux développements d’applications Web se basent aujourd’hui sur le framework Apache Struts. Nous allons reprendre ici la philosophie de cet outil concernant la validation de surface des requêtes.
En deux mots :

Transposition en XSL
L’un des intérêts majeurs de XML est de pouvoir décrire très précisément des structures de données typées, et de pouvoir vérifier la validité d’un document par rapport à cette définition structurelle. Il est donc assez logique ici de traduire le modèle de validation d’Apache Struts en XML Schéma. Le synoptique (dans l’environnement .NET) devient le suivant :

La limite de notre système se trouve dans la partie applicative : « déclencher une action sur le système » (les « … » sur le diagramme précédent), qui sera probablement beaucoup plus simple à réaliser dans un langage de programmation traditionnel comme C# ou Java plutôt qu’en XSL.
Navigation
Nous nous sommes inspirés de Apache Struts pour la validation de surface des requêtes utilisateur. Nous pouvons également reprendre l’approche de cet outil concernant la navigation : on peut tout à fait décrire en XML la navigation des utilisateurs dans notre application Web (le fichier correspondant dans le framework Struts s’appelle « struts-config.xml »).
Mais il faudrait aller un peu plus loin : en fonction des accréditations de nos utilisateurs, il serait intéressant de ne leur présenter que les zones du site auxquelles ils ont accès (certains liens hypertexte, certains portlets doivent disparaître si l’utilisateur n’a pas les droits nécessaires).
De même, si les utilisateur s’authentifient, on peut imaginer que l’on stocke leurs habitudes de navigation (en XML bien entendu), habitudes qu’il faut tracer au fur et à mesure de leur utilisation de notre système. Si notre base de connaissances concernant les utilisateurs est assez fine, rien ne nous empêche d’adapter l’interface aux habitudes de chaque utilisateur. Un exemple simple : dans la suite Office, les menus que vous n’utilisez pas fréquemment sont masqués (mais toujours disponibles). Nous pouvons faire de même dans une interface HTML (un hyperlien permettrait de « démasquer » les options disponibles que nous n’utilisons pas souvent).
Actions du système
En extrapolant un peu, le déclenchement des actions sur un système d’information peut également être décrit en XML. En effet, grâce aux WebServices, nous avons tous les langages nécessaires à :
Mais bien entendu, pour piloter les transformations XML, pour lancer les utilitaires basés sur XML, et pour transmettre les documents à travers un réseau, nous aurons toujours besoin de langages de programmation (C# ici) et de protocoles de communication (HTTP par exemple).
Multi-canal
Dans cet article, nous nous sommes attachés à la production de documents HTML. Langage XSL permettant de générer tout type de document, les mêmes principes peuvent être appliqués à la génération de documents XML (VoiceXML, SVG, X3D), ou de documents imprimables (PS, PDF, RTF…). Le framework que nous avons imaginé a donc tous les atouts pour gérer efficacement la diffusion « multi-canal » des informations et des services.
XML et ses standards connexes sont d’excellents outils complémentaires des plate-formes .NET et J2EE. Ils permettent de développer des applications très flexibles, très modulaires, et qui plus est, portables sur n’importe quel environnement. Java est portable sur tous les OS, mais XML et XSL sont portables sur .NET, J2EE, Python, C… Nous gagnons donc un niveau d’abstraction, et pouvons parler, un peu pompeusement, de méta-framework.
Il faut toutefois tempérer notre enthousiasme concernant le framework imaginé par cet article, et ce pour plusieurs raisons :
Mais cette jeunesse ne doit pas vous empêcher suivre avec attention les évolutions des outils basés sur XML et XSL…
Auteur : Thomas GIL
Copyright : DotNetGuru Ó 2002