Programmer un lecteur de flux RSS avec 4D

Christophe Keromen

Dans cette note technique, nous présentons le concept de syndication, le format RSS et décrivons brièvement ses différentes versions. Nous exploitons ensuite ces connaissances pour réaliser avec 4D 2004 un lecteur RSS compatible avec différentes versions. ♪

- Titre : Programmer un lecteur de flux RSS avec 4D

- Auteur : Christophe Keromen

- Parution : 1 juillet 2006

- Licence : Ce document est issu de https://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- Introduction

- La syndication, outil indispensable des sites web dynamiques

- Pour des nouvelles fraîches

- Une technologie XML facilitant l'intégration

- Diffuser tout type d'information

- Les lecteurs ou agrégateurs

- Pages personnalisés

- Exemple de page personnalisée

- Un lecteur RSS dans 4D

- Présentation d'un flux RSS

- Les versions RSS

- Version 0.9x et 2.0

- Version 1.0

- Résumé des différences entre les versions

- Le lecteur RSS 4D

- L'interface du lecteur 4D

- La réalisation

- Conclusion

- Pour aller plus loin

- Télécharger la base exemple

Introduction

La généralisation de la publication de contenu dynamique sur les sites Web a entraîné l'apparition de nouvelles technologies de consommation de l'information. Parmi elles, la syndication, en particulier sous la forme de flux RSS, constitue désormais un outil de communication incontournable. Après une brève présentation des concepts et des différentes versions de RSS, nous construirons en 4D un exemple de lecteur simple de flux RSS.

La syndication, outil indispensable des sites web dynamiques

L'évolution des sites web vers la publication de contenu dynamique a fait apparaître deux facettes de la même problématique :

- pour un site : comment prévenir les internautes de la publication de nouveautés ?

- pour un internaute : comment se tenir informé de l'évolution des sites détectés comme présentant du contenu intéressant ?

Pour des nouvelles fraîches

La réponse à cette problématique a été apportée par la notion de syndication, principe consistant à proposer une liste des résumés des derniers items ajoutés sur un site. Le résumé contient un lien permettant d'accéder au contenu complet de l'item, se reporter à Wikipedia pour une présentation générale du concept : https://fr.wikipedia.org/wiki/Syndication.

La mise en œuvre de la syndication suppose une séparation entre le contenu et la présentation : un même contenu peut être consulté sous forme de page HTML ou envoyé sous forme de résumé.

Une technologie XML facilitant l'intégration

La technologie RSS (Really Simple Syndication : Syndication Réellement Simple) a popularisé ce concept en s'appuyant sur un format XML. Plusieurs versions du format RSS ont vu le jour et une évolution distincte, ATOM, se rencontre maintenant fréquemment. Le pictogramme indique un site Web proposant des fils RSS.

L'indépendance de l'information par rapport à la présentation, permet en outre aux auteurs de site web d'inclure sur leur propre site des nouvelles provenant d'un autre site, avec garantie d'une mise à jour automatisée. Des sites dédiés à la consultation de flux RSS ont ainsi vu le jour, par exemple Raizonons, agrégateur d'actualités (voir plus loin le paragraphe sur les agrégateurs) : http://raizonons.free.fr/

Raizonons : agrégateur d'actualités

Diffuser tout type d'information

La souplesse de mise en œuvre et d'utilisation de la syndication a amené à étendre son application à la publication de tout type d'information structurée.

Les fameux blogs (web logs ou journaux sur Internet) offrent ainsi généralement une fonction de publication par syndication. L'élargissement de la pratique aux flux multimédia a entraîné l'apparition de nouvelles technologies comme le podcasting.

Les lecteurs ou agrégateurs

On appelle agrégateur un logiciel permettant de surveiller un ou plusieurs fils de syndication, soit en ligne, soit en les rapatriant localement. Les navigateurs proposent une prise en charge plus ou moins complète des flux de syndication : https://fr.wikipedia.org/wiki/Liste_de_lecteurs_RSS

Nous utiliserons par exemple NewsInterceptor sur Windows pour tester nos flux RSS.
http://www.newsinterceptor.com/

Exemple d'interface d'agrégateur

Pages personnalisés

Des agrégateurs en ligne ont aussi vu le jour, permettant de se construire des pages dynamiques sur mesure.
Par exemple my Yahoo! : https://my.yahoo.com/

Mon Yahoo! et les flux RSS

Exemple de page personnalisée

Est-il possible d'appliquer ce concept à l'information sur 4D ?
Vous trouverez ici différents flux RSS proposés par 4D inc : https://us.4d.com/. À partir de ces flux et de quelques autres, je me suis construit la page dynamique Yahoo! suivante :

Exemple de page !Yahoo agrégeant des fils 4D

Yahoo! propose également un agrégateur sous forme de widget (cf. la NT précédente sur ce sujet) :

Un agrégateur en widget : Yahoo! My Headlines

Malheureusement, peu de sites relatifs à 4D proposent des flux RSS. Cette technologie demeure encore sous-employée dans la communauté. C'est d'ailleurs en partie la raison d'être de cette note technique ! En dehors des flux publiés par 4D Inc, je n'ai trouvé que les ressources suivantes :

XML et services Web avec 4D
4DToday.com News
Yodatech | Créateur de sites Web - Expert 4D et 4DBK

Note de DVP.com :
il existe 2 flux RSS 4D sur Developpez.com :
RSS Homepage 4D
RSS Forum 4D

On pourrait considérer que tout fournisseur de produits autour de 4D, en particulier les éditeurs de plugins, trouverait un intérêt à proposer un fil RSS pour permettre de se tenir informé des dernières offres.

Un lecteur RSS dans 4D

Dans la suite de cette note technique, nous allons construire dans 4D un lecteur simplifié de flux RSS.

Présentation d'un flux RSS

Reprenons l'exemple du site Raizonons, et cliquons sur l'icône « RSS » pour consulter le flux brut. En voici un extrait :

<rss version="2.0">
<channel>
<title>Raizonons - Recherche :XML</title>
<link>http://raizonons.free.fr/index.php/recherche/XML</link>
<description>
Recherche dans l'actualité des grands médias francophones. Retrouvez l'intégralité de la recherche sur http://raizonons.free.fr.
</description>
<item>
<title>Tous les résultats de la recherche 'XML'</title>
<link>http://raizonons.free.fr/index.php/recherche/XML</link>
</item>
<item>
<title>Le format Open Document soutenu par Google.</title>
<link>
http://raizonons.free.fr/redir.php?link=http://www.sur-la-toile.com/mod_News_article_1953___.html
</link>
<description>
Il y a quelques jours, nous vous annoncions la prise en compte par Microsoft d'Open Document, le concurrent libre du format Open XML. Plus de 240 entreprises soutiennent le format libre en participant au consortium ODF Alliance. Google vient de rejoindre le consortium. ... Source : Sur la toile - internet
</description>
</item>
…

Nous constatons que ce flux est un flux RSS version 2.0, information importante, car le format diffère notablement suivant la version et que la liste est structurée sous forme d'items composés d'enfants <title>, <link> et optionnellement <description>. Si vous avez suivi un peu la prise en charge d'XML dans 4D et les différentes publications sur le sujet, vous ne devez pas être surpris par cette structure très simple, sinon nous vous invitons à consulter :

· la documentation de 4D ;
· les notes techniques sur le sujet ;
· le « Guide 4D 2004 » aux éditions e-Node et le livre en anglais de David Adams « 4th Dimension Web Services Companion » (Note de DVP : voir sur la page Livres 4D).

Contenu multimédia

Nous avons évoqué plus haut la possibilité de véhiculer des informations sur du contenu multimédia, le podcasting en constituant l'application la plus connue. Cela se réalise en remplaçant l'élément <link> par <enclosure>.

Exemple pour du contenu en mp3 :

<item>
<title>La valise Hervé L</title>
<guid>http://joe.ipradio.example.net/show/54</guid>
<pubDate>Mon, 8 Aug 2005 13:12:12 -0400</pubDate>
<enclosure url="http://joe.ipradio.example.net/show/54" length="4892178" type="audio/x-mp3"/>
</item>

Exemple pour du contenu vidéo :

<item>
<title>Encore moi</title>
<guid>http://sulvietv.example.com/show/2</guid>
<pubDate>Tue, 9 Aug 2005 13:12:12 -0400</pubDate>
<enclosure url="http://katetv.example.com/show/2" length="1894877" type="video/mpeg"/>
</item>

La nature de la ressource multimédia disponible à l'url indiquée par l'attribut url est précisée dans l'attribut type sous forme de type MIME.

Les versions RSS

Il existe plusieurs versions du format RSS. Nous distinguerons deux catégories :

· la version 1.0, issue des spécifications sur RDF ;
· les autres versions 0.xx et 2.0, la version finale de cette branche.

Ainsi la version 1.0 n'a pas grand-chose à voir avec la version 0.9.x ou 2.0 tandis que la version 0.9.x est compatible avec la version 2.0 ! Vous trouverez dans le dossier ‘samples RSS', un exemple en version 1.0 et un autre en version 2.0.

Version 0.9x et 2.0

La structure de ces versions est très simple, c'est celle que nous avons déjà rencontrée précédemment :

<rss version="2.0">
<channel>
<title>…</title>
<description>…</description>
<link>…</link>
</channel>

Vous en trouverez les spécifications ici :
https://cyber.harvard.edu/rss/rss.html
(traduction en français : http://www.stervinou.com/projets/rss/)

Voici un extrait de la traduction en français  de la spécification :

« Au niveau le plus élevé, un document RSS est un élément <rss>, avec un attribut obligatoire appelé version, qui spécifie la version de RSS à laquelle le document est conforme. S'il est conforme à cette spécification, l'attribut version doit être 2.0. » Nous exploiterons cet énoncé dans notre code pour distinguer cette famille de la plus complexe version 1.0.
La version 2.0 date de l'automne 2002. Notons que sont obligatoires les enfants de <channel> suivants : <title>, <link>, <description>. Suivent un ensemble d'enfants facultatifs que nous n'exploiterons pas dans notre exemple. En outre, un <channel> peut contenir n enfants <item>. « Tous les éléments d'un <item> sont facultatifs, cependant au moins le <title> ou la <description> doivent être présents. »

La spécification précise également quelques contraintes de contenu :

« Dans RSS 0.91, certains éléments sont restreints à 500 ou 100 caractères. Il ne peut pas y avoir plus de 15 <items> dans un <channel> 0.91. Il n'y a pas de limites de longueur de texte ou de limites au niveau du XML dans RSS 0.92 et les versions ultérieures ».

Version 1.0

Vous en trouverez les spécifications officielles, datant de décembre 2000, ici :
RSS 1.0 : http://web.resource.org/rss/1.0/

Cette version élaborée par un groupe de travail indépendant (RSS Working Group), s'appuie sur RDF (Resource Description Framework), un langage de représentation de l'information sur le Web : http://www.w3.org/TR/REC-rdf-syntax/, issu des travaux du W3C.

Pour ceux qui ont déjà goûté aux charmes des RFC, ils ne seront pas surpris de constater que cette mouture est nettement plus complexe que la précédente. Elle présente l'avantage, tout comme Atom, de prendre en compte les espaces de noms que l'autre branche ignore.

La structure de base d'un document RSS est la suivante :

· déclaration XML,
· conteneur,
· description du canal,
· description de l'image (optionnelle),
· description du ou des articles,
· description du champ de saisie (optionnelle).

Exemple de flux RSS 1.0 :

<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/">

<channel rdf:about="http://20six.fr/xml-ws/rss">
… contenu complexe de channel
<items>
<rdf:Seq>
<rdf:li resource="http://20six.fr/xml-ws/art/1191957"/>
<rdf:li resource="http://20six.fr/xml-ws/art/1099848"/>
<rdf:li resource="http://20six.fr/xml-ws/art/199701"/>
Etc.
</rdf:Seq>
</items>
</channel>
<item rdf:about="http://20six.fr/xml-ws/art/1191957">
<title>La question qui revient le plus souvent </title>
<link>http://20six.fr/xml-ws/art/1191957</link>
<description>
<p>La question qui revient le plus souvent : quel bon
coupé
</description>
<dc:publisher>xml-ws</dc:publisher>
<dc:creator>xml-ws</dc:creator>
<dc:subject>La question qui revient le plus souvent </dc:subject>
<dc:date>2006-04-03T07:41:38+0200</dc:date>
</item>
<item rdf:about="http://20six.fr/xml-ws/art/1099848">
<title>StrikeIron WebServices Analyser</title>
<link>http://20six.fr/xml-ws/art/1099848</link>
<description>
<p>Honte sur moi
coupé
</description>
<dc:publisher>xml-ws</dc:publisher>
<dc:creator>xml-ws</dc:creator>
<dc:subject>StrikeIron WebServices Analyser</dc:subject>
<dc:date>2006-02-20T07:36:07+0100</dc:date>
</item>
Etc.

Notons que ce flux présente l'inconvénient de véhiculer dans la description des items des informations de présentation html, ce qui ne devrait pas être le cas.

Résumé des différences entre les versions

La principale différence entre la branche 0.91, 2.0 et la branche 1.0 se trouve au niveau de l'élément <channel> :

· la branche 0.91, 2.0 véhicule le contenu (<items>) comme enfant de l'élément <channel>,
· tandis que la branche 1.0 propose le contenu (<items>) au même niveau que l'élément <channel>.

Notre programme devra en tenir compte.

Vous trouverez sur :
https://developer.mozilla.org/fr/docs/Archive/RSS/Premiers_pas/Présentation_de_RSS
http://www.opikanoba.org/xml/040315/
une très intéressante rétrospective de l'évolution des différents formats RSS.

Version non conforme

Notons au passage que les flux RSS servis par 4D Inc à l'url https://us.4d.com/ ou https://us.4d.com/ contiennent un piège :

<rss version="1.0">
<channel>
<title>4D Announcements</title>
<description>Listing of the latest 4D Announcements.</description>
<link>http://www.4d.com/</link>
<item>

Ils indiquent respecter la version 1.0 de rss alors que cette version n'existe pas, puisqu'on est passé de 0.94 à 2.0 ! Notre lecteur ne pourra les relire qu'en y introduisant un contournement spécifique.

Validation des flux RSS

Vous pouvez constater que la qualité et le contenu des flux RSS sont très variables.

C'est pourquoi il existe des pages de validation :
http://www.feedvalidator.org/
http://validator.w3.org/
et par le W3C proposant une API de service Web :
http://rss.scripting.com/

Le lecteur RSS 4D

L'interface du lecteur 4D

Interface du lecteur 4D

Une liste déroulante présente une sélection de flux RSS consultables.

Le bouton portant l'icône RSS permet de déclencher la réception du flux RSS et son analyse par 4D.

Le bouton XML permet de copier dans le presse-papiers le flux RSS. Les trois informations Nouvelles, Description, URL sont extraites en exploitant les éléments respectivement <title>, <description> et <link>. Un clic sur le contenu du champ URL avec un enfoncement de la touche control sur un PC ou commande sur un Mac permet d'accéder au détail de l'item dans un navigateur.

La réalisation

Si l'on fait abstraction de l'interface, très simple, l'essentiel de la programmation se trouve dans la méthode : RSS_getStream. Elle interroge la source XML et l'analyse pour construire l'arbre DOM en mémoire grâce à DOM Analyser source XML.

Méthode RSS_getStream

code 4D

` ----------------------------------------------------
` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 09/01/06, 09:02:44
` ----------------------------------------------------
` Methode : RSS_getStream
` Description :
` relit un flux RSS
` d'après un exemple de Rob Laveaux dans XML Plugin Demo v2.0
`-> This method will retrieve a RSS file from the given URL
` and will fill the arrays with the title, description and link
` RSS (RDF site summary or rich site summary) is a standard for publishing
` site summaries on the web. It has many applications, but is mostly used to
` retrieve headlines from news sites
`
` Parametres :
` $1:TEXTE:URL
` $2:POINTEUR:Tableau titres
` $3:POINTEUR:Tableau description
` $4:POINTEUR:Tableau liens
`
` Version : 1
` Appel : RSS_getStream ($_vt_URL;->Title;->Description;->Link)
` ----------------------------------------------------

C_TEXTE($1;$vt_URL)
$vt_URL:=$1

C_POINTEUR($2;$3;$4;$vp_Titles;$vp_Descriptions;$vp_Links)

$vp_Titles:=$2
$vp_Descriptions:=$3
$vp_Links:=$4

ZTAB_sizeArrays (0;$vp_Titles;$vp_Descriptions;$vp_Links)

C_BOOLEEN($_vb_ifValidate)
$_vb_ifValidate:=Faux  `pour la substitution d'entités depuis la DTD

` interroge la source du flux et le charge en mémoire
C_TEXTE($_vt_refRoot)
$_vt_refRoot:=DOM Analyser source XML($vt_URL;$_vb_ifValidate)

Si (ok=1)

C_TEXTE($_vt_element)
DOM LIRE NOM ELEMENT XML($_vt_refRoot;$_vt_element)

Au cas ou
: ($_vt_element="rss")
C_TEXTE($_vt_rssVersion)
DOM LIRE ATTRIBUT XML PAR NOM($_vt_refRoot;"Version";$_vt_rssVersion)
Si ($_vt_rssVersion="2.0") | ($_vt_rssVersion="0.91") | ($vt_URL="http://www.4d.com/@")

C_TEXTE($_vt_xpathItem)
$_vt_xpathItem:="/rss/channel/item["
RSS_parse ($_vt_refRoot;$vp_Titles;$vp_Descriptions;$vp_Links;$_vt_xpathItem)

Sinon
ZTAB_sizeArrays (1;$vp_Titles;$vp_Descriptions;$vp_Links)
$vp_Titles->{1}:="Version non prise en charge"
$vp_Descriptions->{1}:=$_vt_rssVersion
$vp_Links->{1}:="http://www.stervinou.com/projets/rss/"
Fin de si

: ($_vt_element="rdf:rdf")  `v 1.0
Si (Vrai)
C_TEXTE($_vt_xpathItem)
$_vt_xpathItem:="/RDF/item["
RSS_parse ($_vt_refRoot;$vp_Titles;$vp_Descriptions;$vp_Links;$_vt_xpathItem)

Sinon   `autre méthode par parcours des enfants
RSS_v1_parse ($_vt_refRoot;$vp_Titles;$vp_Descriptions;$vp_Links)
Fin de si

Sinon
DOM LIRE ATTRIBUT XML PAR NOM($_vt_refRoot;"xmlns";$_vt_rssVersion)
ZTAB_sizeArrays (1;$vp_Titles;$vp_Descriptions;$vp_Links)
$vp_Titles->{1}:="Version non prise en charge"
$vp_Descriptions->{1}:=$_vt_rssVersion
$vp_Links->{1}:="http://www.stervinou.com/projets/rss/"
Fin de cas

DOM FERMER XML($_vt_refRoot)
Fin de si

Puis la routine RSS_parse analyse les éléments <items> pour remplir trois tableaux textes contenant les contenus des éléments <title>, <description> et <link>. Le tableau des éléments <title> relus est présenté en utilisant une listbox.

Méthode RSS_parse

code 4D

` ----------------------------------------------------
` Nom utilisateur (OS) : christophe Keromen
` Date et heure : 18/08/06, 21:53:22
` ----------------------------------------------------
` Methode : RSS_parse
` Description :
` relit un flux RSS
`
` Parametres :
` $1:TEXTE:ref racine XML
` $2:POINTEUR:Tableau titres
` $3:POINTEUR:Tableau description
` $4:POINTEUR:Tableau liens
` $5:TEXTE:expression XPath pour item
`
` Version : 1
` Appel : RSS_parse ($_vt_refRoot;$vp_Titles;$vp_Descriptions;$vp_Links;$_vt_xpathItem)
` ----------------------------------------------------

C_TEXTE($1;$_vt_refRoot)
$_vt_refRoot:=$1

C_POINTEUR($2;$3;$4;$vp_Titles;$vp_Descriptions;$vp_Links)

$vp_Titles:=$2
$vp_Descriptions:=$3
$vp_Links:=$4

C_TEXTE($5;$_vt_xpathItem)
$_vt_xpathItem:=$5

C_ENTIER LONG($vl_Count)
$vl_Count:=1

Repeter

`on recherche les items par une expression XPath
C_TEXTE($_vt_ItemFound)
$_vt_ItemFound:=DOM Chercher element XML($_vt_refRoot;$_vt_xpathItem+Chaine($vl_Count)+"]")

Si (ok=1)

` Resize the arrays
ZTAB_sizeArrays ($vl_Count;$vp_Titles;$vp_Descriptions;$vp_Links)

` enfants de l'element item
`<item>
`   <title>Nouveau Centre de Formation 4D</title>
`   <link>http: >> 4DToday.com/home†c=Date&d=2006-1-9</link>
`   <description>4D SA a annoncé le lancement du nouveau Centre de Formation 4D.
`Le centre de formation 4D, s'enrichit d'un espace dédié en ligne,
`pour plus d'interaction, plus de personnalisation afin de mieux
`s'adapt à vos demandes.</description>
`</item>

C_TEXTE($_vt_valeurElement)

$_vt_valeurElement:=DOM_LireValeurElement_XPath ($_vt_ItemFound;"title")
Si (ok=1)
$vp_Titles->{$vl_Count}:=$_vt_valeurElement
Fin de si

$_vt_valeurElement:=DOM_LireValeurElement_XPath ($_vt_ItemFound;"description")
Si (ok=1)
$vp_Descriptions->{$vl_Count}:=$_vt_valeurElement
Fin de si

$_vt_valeurElement:=DOM_LireValeurElement_XPath ($_vt_ItemFound;"link")
Si (ok=1)
$vp_Links->{$vl_Count}:=$_vt_valeurElement
Fin de si

ok:=1
Fin de si

$vl_Count:=$vl_Count+1

Jusque (ok=0)

La seule différence concernant les deux branches de versions du format RSS se trouve dans la manière de localiser les éléments <items>. Nous utilisons pour cela une expression XPath :

· « /rss/channel/item[i] » pour la version 2.0 ;
· « /RDF/item[i] » pour la version 1.0.

Remarquons que, quoique la structure XML du flux 1.0 contienne des espaces de noms, par exemple,

<rdf:RDF>
<channel rdf:about="http://20six.fr/xml-ws/rss">
<title>XML et services Web avec 4D</title>

notre expression XPath n'en tient pas compte. En effet, la commande 4D DOM Chercher element XML ne gère pas les espaces de noms.

Note :
L'emploi de l'API SAX est particulièrement adapté pour ce cas de figure où les éléments à relire sont connus d'avance et ne demandent pas de maintenir un contexte hiérarchique pour leur exploitation. Cependant, l'implémentation 4D exploite un document XML sur disque. Il aurait donc fallu interroger la source de données, récupérer le flux XML, l'enregistrer sur disque, puis analyser le résultat. L'approche DOM permet dans 4D de recevoir directement le flux et de l'analyser en mémoire, c'est pourquoi nous l'avons retenue.

Conclusion

Dans cette note technique, nous avons présenté le concept de syndication, introduit le format RSS et décrit brièvement ses différentes versions. Nous avons ensuite exploité ces connaissances pour réaliser avec 4D 2004 un lecteur RSS compatible avec ces différentes versions. Dans une prochaine note technique, nous nous attellerons à la publication depuis 4D d'information au format RSS.

Pour aller plus loin

Technical Note 03-20 : 4D 2003 and RSS (en anglais)

Tutoriels en ligne :

https://www.mnot.net/rss/tutorial/index.html
http://www.w3schools.com/rss/default.asp

Introduction à RSS 1.0 : http://xmlfr.org/documentations/tutoriels/041022-0001

Exemples 2.0 : http://www.xml.com/2002/12/18/examples/rss20.xml.txt

FAQ Yahoo : http://fr.my.yahoo.com/s/intl/fr/faq/rss

Spécifications officielles

RSS 1.0 :
http://web.resource.org/rss/1.0/

RSS 2.0 :
https://cyber.harvard.edu/rss/rss.html
traduction en français : http://www.stervinou.com/projets/rss/

Télécharger la base exemple

Télécharger la base exemple.