I. Qu'est-ce qu'un flux RSS ?

A l'origine, RSS signifiait Rich Site Summary.

Dans sa dernière spécification, la 2.0, RSS signifie désormais Really Simple Syndication.

Un flux RSS est une grappe de texte structurée en XML, provenant d'un site web quelconque, et qu'en général on extrait pour le republier sur un autre site web. Cela permet de concevoir son propre site, en syndiquant des informations choisies extraites d'autres sites web. Ces sites facilitent l'exportation de leurs informations sous forme de flux RSS. Sur les sites ou les blogs, les flux RSS sont facilement repérables grâce aux icônes suivants : Image non disponibleImage non disponibleImage non disponible

De nombreuses applications, agrégateur de flux RSS, existent déjà. Mais ce qui nous intéresse, c'est de pouvoir intégrer ces flux d'information dans nos propres applications web. Par exemple les actualités du jour, la météo, la bourse, ou encore la liste des derniers articles techniques publiés dans MSDN Magazine...

II. Le Projet XMLRAD Etape par Etape

A. Création du projet

Vous savez que dans un projet XMLRAD, le code de gestion est totalement découplé de la présentation. Nous écrirons seulement deux lignes de code de gestion uniquement pour une conversion de date, et ce en C#. On utilisera SharpDevelop, outil libre et open source.
Assurez vous qu'il soit bien installé ainsi que le framework .NET 1.1.

Démarrez l'environnement de développement XMLRAD, et créez un nouveau projet. Sélectionnez Projet Simple.

Image non disponible

Dans la fenêtre suivante, indiquez le nom du nouveau projet : RSSReader, l'environnement de développement : SharpDevelop. Cliquez sur le bouton << Options Avancées et décochez la case : [Oui, je vais utiliser une base de données pour ce projet]. Cliquez sur Suivant et vous devriez aboutir sur la fenêtre suivante. Si on vous demande de migrer à partir d'une version antérieure de XMLRAD, cliquez sur Annuler.

Image non disponible

B. Création du XMLService FormRSSReader

Un Module est un conteneur de XMLServices.
Un XMLService est un processus responsable de la production d'une page web particulière.

Dans le module RSSReaderWM Nous allons créer un nouveau XMLService nommé FormRSSReader.
(L'adresse d'invocation par le navigateur sera : http://stardev/RSSReaderBin/Global.aspx/FormRSSReader).
Cliquez sur le module RSSReaderWM puis sur le bouton Ajout de XMLService :

Image non disponible

Un assistant vous propose des modèles de XMLServices. Cliquez sur l'onglet Divers, puis sur Fiche Vide et Validez.

Image non disponible

Une nouvelle page vous demande le nom du XMLService. Saisissez FormRSSReader dans la zone de saisie Nom et cliquez sur le bouton Terminer.

Image non disponible

L'assistant a terminé sa tache et vous pouvez désormais travailler votre XMLService. Dans un premier temps, nous allons rassembler les données utiles de notre future page web, puis nous nous occuperons de la mise en forme.
Sur l'écran suivant, vous pouvez remarquer qu'un gabarit graphique par défault (Modèle Divers / Page Vide) a été appliqué mais ne vous inquiétez pas, vous pouvez tout changer si vous le souhaitez.

Image non disponible

C. Capturer le flux RSS avec HttpInvoke

La section XMLGram d'un XMLService permet de décrire les instructions qui vont produire et/ou extraire des données. Parmi ces instructions nous trouvons HttpInvoke.

Nous allons ajouter une instruction HttpInvoke dans le XMLGram. Le rôle de HttpInvoke est d'invoquer une url, et de récupérer le flux résultat.
Cliquez sur le menu XMLGram et en haut à droite de la fenêtre dans XMLGramExplorer, Sélectionnez le composant HttpInvoke Image non disponible. Donnez lui un nom, par exemple StreamReader.
Effectuez un clic droit sur la première instruction par défault : Params et sélectionnez le menu Insert After. Ensuite remplissez les paramètres de l'instruction ainsi :

  • Méthode : GET
  • URL : http://msdn.microsoft.com/msdnmag/rss/rss.aspx?tech=ASP&x=27&y=9
  • Identifiant HTTP :
  • Mot de Passe HTTP :
  • Asynchrone : non coché
  • Récuperer le document et le rajouter dans le document de sortie : True
  • Selection (XPath) : /rss
  • Type de document de sortie : OutputDoc
  • Nom du champ de sortie :


Image non disponible

L'url spécifiée est celle invoquant le flux RSS des articles ASP/ASP.NET chez MSDN Magazine de Microsoft.
On demande à l'instruction d'ajouter le flux résultat dans le document de sortie (OutputDoc), qu'on exploitera plus tard pour la transformation XSL (visualisation des données).
La sélection XPath indique le chemin de la grappe XML à récupérer dans le flux résultat. Il aurait pu être possible que seule une partie du RSS nous intéresse.

Voyons maintenant comment XMLRAD exécutera cette instruction et stockera le flux de données. Cliquez sur le menu XML du XMLService.
La grappe XML (Output) s'est enrichie du flux RSS provenant de MSDN Magazine :

Image non disponible

Remarquez l'élément <rss>, qui est la racine de la grappe XML constituant le fil RSS récupéré par HttpInvoke.
Maintenant que le mécanisme de production des données est en place, nous allons passer à la représentation visuelle.
Cliquez sur le menu XSL du XMLService.

D. Fondations du visuel avec XSLStudio

Dans l'éditeur XSLStudio, cliquez sur le texte "Ceci est un formulaire simple". Choisissez le composant DataTable dans la barre centrale rubrique Data.
Dans la partie basse de XSLStudio, effectuez un clic droit sur l'élément <p>, et sélectionnez Insert Before.

Image non disponible

Un assistant va s'ouvrir et demander quel noeud XML va servir de racine d'alimentation (Dataset) de notre table. Sélectionnez le noeud <rss> et cliquez sur Next.
Il vous demande ensuite le chemin d'accès aux "record node" qui représente le noeud racine des informations à afficher sur chaque ligne du tableau. Sélectionnez le noeud <item> (enfant de /rss/channel).

Image non disponible

L'assistant vous demande quels sont les champs que vous voulez afficher dans le tableau. Sélectionnez les éléments tels que le screen suivant :

Image non disponible

Voilà le résultat obtenu, que nous allons retravailler :

Image non disponible

E. Cuisiner le HTML avec XMLRAD

On va maintenant oublier un peu les assistants, car on pourrait faire croire aux débutants XMLRAD que rien n'est possible sans eux.
Au contraire, on peut partir complètement de zéro, mais ce serait revenir quelques années en arrière. En revanche, nous allons maintenant rentrer dans le détail du HTML produit par le XMLService et apporter des modifications de manière à améliorer la présentation de notre flux RSS.

1. Modifier les titres

Pour modifier un titre, cliquez dessus dans XSLStudio. Dans la partie basse, le flux produit par le processeur XSL s'affiche.
Ci dessous, nous avons cliqué sur le titre : title. En bas nous voyons que "title" est un texte inséré dans une balise TD. Nous le modifions et confirmons avec CTRL + S pour sauvegarder.
Répétez cette opération pour chaque colonne.

Image non disponible

2. Supprimer la colonne link puis mixer le titre et le link respectif

Cliquez sur le titre "Link". Dans la partie basse de l'éditeur effectuez un clic droit sur la balise TD, et sélectionnez Supprimer.
Vous venez de supprimer la colonne TD de la ligne de titre (TR en HTML). Cette ligne TR a été généré lorsque le template rss a été rencontré par le processeur XSL.
Voyons le template rss, cliquez à droite sur le bouton XSL et sélectionnez le template rss.



Image non disponible

Une balise TR est générée ainsi que des TD dans lesquelles on retrouve les titres de notre tableau. A la fin, une instruction xsl : <xsl:apply-templates select="channel/item"/> indique au processeur xsl de déclencher les templates adaptés pour chaque élément item rencontré, enfant de l'élément channel.
Toujours dans l'exploreur XSL, cliquez sur le template : <xsl:template match="item"/>

Image non disponible

Nous voyons qu'à chaque fois que la balise item est "matchée", une TR est générée, avec des colonnes TD à l'intérieur desquelles on extrait des informations du XML (OutputDoc) qu'on avait prévisualisé précédemment dans ce tutorial.
D'ailleurs si vous cliquez sur le bouton XML (en bas à droite dans XSLStudio), la structure XML de votre document apparaît, en surbrillance l'élément courant. Si vous cliquez sur un autre élément, le chemin relatif de cet élément par rapport à l'élément courant est affiché. Dans l'image ci-dessous, l'élément item est en surbrillance car c'est l'élément courant. En effet, nous sommes dans le template qui est chargé de traiter le noeud item, donc lorsque le processeur xsl arrivera sur l'élément item, il déclenchera ce template, item sera l'élément courant.

Image non disponible

Comme pour le titre du tableau où nous avons supprimé la colonne Description, nous allons supprimer la colonne Description de la ligne générée pour chaque item.

Image non disponible

Nous allons maintenant afficher le titre en tant que lien renvoyant vers l'article respectif. Pour cela cliquez sur la partie blanche juste sous la zone Titre, vous allez visualiser uniquement la partie qui s'occupe d'afficher le contenu de cette colonne. Puis pour découvrir et changer un peu, cliquez sur le bouton Source dans l'explorateur d'XSLStudio. Profitez-en pour afficher la structure XML également, positionnez la vers l'élément item, cela va nous servir de repère.

Image non disponible

Nous allons écrire du HTML à la main cette fois (on a toujours le choix), en encapsulant le titre dans un lien <a href=""> dont la référence sera justement le contenu de l'élément link. Voici la modification à apporter :

Image non disponible

L'élément link est intégré dans le html à l'aide d'accolades {} et non d'une instruction xsl:value-of, car il doit être inséré dans un attribut et non un élément. Remarquez la barre d'état du navigateur, le lien a bien été pris en compte (je survolais le lien avec la souris au moment de la capture écran).
Ici nous avons intégré un lien, mais on peut injecter le html que l'on souhaite, une image comme une applet flash par exemple.

3. Déplacer la description de l'article sous le titre dans un <DIV> caché

Nous allons encore modifier la structure html du résultat, cette fois en supprimant la colonne Description. A la place nous ajouterons un lien à la fin de chaque Titre, et le fait de cliquer successivement sur ce lien fera apparaître ou disparaître la description dans un bloc (DIV) situé juste sous le titre.
Supprimez la colonne description, qui prend beaucoup de place, et qu'on ne visualisera que sur commande.
On va ensuite ajouter une image avec lien juste après le contenu le la colonne titre :
Cliquez à nouveau sur la zone blanche juste en dessous du titre de colonne "Titre". Dans la palette HTML, choisissez le composant ImageLink, puis dans XSLStudio, effectuez un clic droit sur <xsl:value-of select="title">, ce qui aura pour effet d'ajouter l'image juste après le contenu du titre de cette ligne.

Image non disponible

Puis choisissez une image de votre choix dans l'explorateur d'image. XMLRAD se charge d'insérer le chemin relatif dans la balise <img>. Le résultat obtenu ressemble à celui-ci :

Image non disponible

On va passer en mode source, puis ajouter une balise <DIV> nommée sous l'image que l'on vient d'ajouter. Dans le style de ce bloc, on attribuera une couleur de fond (background-color) et de texte (color), et on cachera le bloc (display:none).
On ajoutera aussi une commande javascript dans l'évènement onclick du lien dans lequel l'image est placée :

 
Sélectionnez
onclick="ShowHide('Desc{position()}');return false"

On supprime aussi le lien href par défault en le remplaçant par un point (.). Seul le déclenchement du onclick nous intéresse ici lorsque l'on cliquera sur l'image. C'est pour cela que nous avons ajouté le morceau de code js : return false; qui évite au navigateur de chercher à aller sur le lien href après avoir traité le onclick.

ShowHide est une fonction issue de la bibliothèque Javascript (Voir Appendix de la bibliothèque xslc.js ) de l'environnement XMLRAD. Elle prend en paramètre l'identifiant d'un élément du DOM, et se charge de cacher ou afficher cet élément selon son état initial, se comportant comme un interrupteur.

position() est une expression xsl qui renvoie la position du noeud XML en cours de traitement par le processeur XSL. Nous nous en servons pour être surs d'attribuer un nom différent à chaque bloc généré.
Lorsque nous voudrons Afficher ou Cacher un bloc, il nous sera possible de localiser un bloc distinctement des autres grâce à son nom unique.

Dans le screen ci-dessous, étudiez le code que nous avons modifié dans XSLStudio. Nous n'avons pas ajouté grand chose, mais c'est efficace.
Vous voyez le code modifié en surbrillance couleur.

Image non disponible

Si on repasse en mode Normal dans XSLStudio, alors voici la vue correspondante :

Image non disponible

Cette vue "en grille" est souvent utile et claire pour appréhender la structure html. Ne vous étonnez pas si vous ne voyez pas le nouveau bloc DIV dans la fenêtre Preview, c'est normal puisque nous lui avons demandé d'être caché (style = display:none).

Vous pouvez maintenant exécuter le projet et vérifier l'affichage de la description lorsque vous cliquez sur le lien image dans la zone titre.

III. Ajouter du code de gestion

Vous pouvez remarquer que jusqu'à présent, nous n'avons saisi aucune ligne de code conduisant à la production de donnéés, l'instruction HttpInvoke s'en étant chargé.
La date de publication des articles fournie par le flux RSS n'est pas vraiment au format idéal pour un francophone. Cela nous donne une bonne occasion de voir comment on va pouvoir ajouter des informations dans le XML, en convertissant les dates de type Tue, 11 Oct 2005 00:00:00 GMT au format de type 11/10/2005.
* Pour ce faire nous devons trouver un moyen de :

  • Parcourir tous les éléments item
  • Lire l'élément enfant item/pubDate
  • Convertir sa valeur vers le nouveau format date
  • Réinjecter le résultat dans le XML (Output), qu'on exploitera dans le XSL.

F. Parcourir tous les éléments item

En programmation classique, nous utiliserions une classe XMLReader ou équivalent, de façon à déplacer un curseur XML sur le flux RSS.

XMLRAD nous évite encore une fois de taper des lignes de code car l'instruction Match réalise ce travail... Une minute pour mettre en place l'instruction et aucun bug possible !

Retournez dans l'éditeur XMLGram, sélectionnez l'instruction Match, donnez lui le nom Items, effectuez un clic droit sur la dernière instruction HttpInvoke,
et enfin cliquez sur le menu Insert after.

Image non disponible

  • L'instruction Match devra parcourir le flux RSS : dans la source de données Output
  • Le chemin XPath pour matcher chaque article est : /document/rss/channel/item
  • Enfin nous demandons à l'instruction de remplir le context, car nous nous en servirons pour récupérer la date à formatter.
Image non disponible

G. Ouvrir SharpDevelop et le fichier source associé au module RSSReaderWM

Si créer des applications .NET avec XMLRAD vous intéresse, vous pouvez lire ce tutoriel écrit par Jean Philippe Bempel (RDM) :
Créer une application .NET avec XMLRAD

Nous allons enfin taper une ligne de code ! Ouf sauvés !
Quel est le moyen de prendre la main à chaque fois que l'instruction Match nommée Items va s'arrêter sur un élément item (se comportant comme un itérateur en quelque sorte) ?
Vous devez connaître le workflow d'exécution d'une instruction XMLGram (Appendix 13), et donc savoir qu'à chaque fois qu'une instruction Match itère sur un élément, les gestionnaires d'évènement BeforeInternalInstruction et AfterInternalInstruction sont exécutés.

Nous allons ouvrir le projet SharpDevelop sous jacent à l'application et écrire le gestionnaire d'évènement AfterInternalInstruction nécessaire. Démarrez SharpDevelop et ouvrez le projet XMLServer.cmbx situé dans le dossier \Bin de notre application.

Image non disponible

Ensuite dans la fenêtre projet de SharpDevelop, effectuez un double clic sur RSSReaderWM.cs qui est le fichier source lié à la prise en charge des traitements en code du module RSSReaderWM.

Décommentez

 
Sélectionnez

// private XMLComponent.WebForm Updatepublishers;

et remplacez UpdatePublishers par FormRSSReader (le nom de notre XMLService).

Les projets SharpDevelop ne disposent pas de mode designer pour afficher les modules dans lequels on place des composants XMLService, à l'instar d'autres environnements comme Delphi Studio ou Visual Studio.
Par conséquent tout le code doit être écrit par vos soins, dont l'instanciation des composants. C'est pour cette raison que les fichiers .cs correspondant à chacun des modules intègre par défault du code sample, très utile comme guide.
Il suffit de s'appuyer dessus et de personnaliser en rapport avec notre XMLService.

H. Ecrire le code de gestion lié à l'évènement FormRSSReader.AfterInternalInstruction

Après avoir déclaré la variable private : private XMLComponent.WebForm FormRSSReader;, nous devons l'instancier dans la méthode InitializeComponent().
Nous ajoutons un delegate pour gérer l'évènement AfterInternalInstruction. Le nom de la méthode qui jouera ce rôle est FormRSSReader_AfterInternalInstruction.

 
Sélectionnez
private void InitializeComponent()
		{
			FormRSSReader = new XMLComponent.WebForm();
			FormRSSReader.AfterInternalInstruction += new XMLComponent.TAfterInternalInstructionEventHandler(FormRSSReader_AfterInternalInstruction);
		}

Il nous reste à coder cette méthode delegate, dans laquelle nous allons réaliser la conversion de date.

Nous utiliserons les classes .NET : DateTime et Convert. Cette dernière est étonnante car elle va être capable d'ingurgiter une date au format RFC 1123 (format de date utilisé dans RSS2) sans broncher !

 
Sélectionnez
private void FormRSSReader_AfterInternalInstruction(XMLCLX.IXMLInstruction XMLInstruction, XMLComponent.TAfterInternalInstructionEventArgs e)
		{
			DateTime dt;
			
			if (XMLInstruction.Name == "Items")
			{
				dt = Convert.ToDateTime(Context.GetValue("pubDate"));
				e.Input.SetValue("pubDateFormatted", dt.ToString("dd/MM/yyyy"));
			}
		}

Vous remarquez que nous ajoutons la date convertie dans le container Input alors que traditionnelement c'est dans Output que nous ajoutons nos données de gestion.
Il s'agit d'une particularité lié à l'instruction Match. Ce n'est pas une instruction qui produit des données, mais qui s'appuie sur des données déjà existantes. C'est la raison pour laquelle l'élément matché à chaque itération est accessible dans le container Input.
Lorsqu'on utilise un instruction DBExtract, cette dernière produit des données dans le XML à chaque fetch de la base de données. C'est donc dans le container Output que l'élément courant est placé, puisqu'il vient d'être créé.

Il reste une dernière chose : Compiler le projet et vous pourrez passer aux tests pour vérifier la qualité de votre travail :-)

IV. Afficher la date formattée en face de chaque article

Vous pouvez quitter SharpDevelop. Revenez à l'environnement XMLRAD, ouvrez le XMLService FormRSSReader et cliquez sur le bouton XML.
Cliquez ensuite sur le bouton Regenerate XMLData pour être sur d'obtenir un fichier XML exemple à jour.
Vous devriez observer la structure XML suivante, en remarquant la présence du nouvel élément enfant de item : pubDateFormatted.

Image non disponible

Retournons à présent dans le menu XSL qui va nous permettre de mettre à jour la mise en forme en remplaçant l'élément pubDate par pubDateFormatted.
Cliquez sur une date dans la fenêtre Preview de XMLStudio, et dans la partie basse, remplacez le xsl:value-of select="pubDate" par xsl:value-of select="pubDate".

Image non disponible

Vérifiez dans la fenêtre preview, maintenant la date formattée par votre code est affichée :

Image non disponible

V. Conclusion

L'aspect fortement détaillé de chacune des étapes de cet article pourrait incidieusement faire croire au lecteur que tout ça est bien compliqué.
J'ai volontairement pris soin de ne pas macher les étapes de construction du projet, afin que les débutants sur XMLRAD, de plus en plus nombreux à s'intéresser à cet environnement, ne soient pas perdus.
La prise en main d'XMLRAD peut sembler déconcertante car cet environnement ne ressemble en rien aux autres, à part peut-être à un Cocoon sous stéroides puissance 10 ;-) Il faut retenir que pour réaliser la démo préalable à l'écriture de cet article, il m'a fallu très peu de temps, tout juste quelques minutes. Alors maintenant que vous avez suivi jusqu'au bout cet apprentissage, essayez tout(e) seul(e) comme un(e) grand(e) avec d'autres flux RSS.
Je projette une suite à cet article, dans lequel on ajoutera une liste de plusieurs fils RSS, ce qui nous permettra de voir comme gérer le passage de paramètres, entre autres.

A bientôt, et n'hésitez pas à revenir sur ce tutorial dans le forum XMLRAD.

Sylvain James