Créer un lecteur RSS en 5 minutes

Très mauvaisMauvaisMoyenBonExcellent (3 votes) 
Loading...Loading...

Aujourd’hui, je suis tombé par hasard sur une petite classe bien pratique : SyndicationFeed. Cette classe, apparue dans le framework 3.5, permet de manipuler des flux de syndication (comme RSS 2.0 ou Atom 1.0) avec un minimum de code. On peut l’utiliser pour créer et diffuser des flux, ou pour lire des flux existants.

Par exemple, voilà comment récupérer le fil d’actualité de Google News et afficher son titre, son lien d’origine et les titres de ses articles :

string url = "http://news.google.fr/nwshp?hl=fr&tab=wn&output=rss";
using (XmlReader reader = XmlReader.Create(url))
{
    SyndicationFeed feed = SyndicationFeed.Load(reader);
    Console.WriteLine(feed.Title.Text);
    Console.WriteLine(feed.Links[0].Uri);
    foreach(SyndicationItem item in feed.Items)
    {
        Console.WriteLine(item.Title.Text);
    }
}

Simple, non ? :)

Tirons maintenant parti des facilités de binding de WPF pour créer un petit lecteur RSS graphique :

<Window x:Class="TestFeeds.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Minimalist feed reader" Height="286" Width="531">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <DockPanel Grid.Row="0">
            <Button Name="btnGo"
                    DockPanel.Dock="Right"
                    Width="50"
                    Content="Go"
                    Click="btnGo_Click" />
            <TextBox Name="txtUrl" />
        </DockPanel>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <ListBox Name="lstFeedItems"
                     Grid.Column="0"
                     DisplayMemberPath="Title.Text" />
            <GridSplitter Grid.Column="1"
                          VerticalAlignment="Stretch"
                          Width="3"
                          ResizeBehavior="PreviousAndNext"
                          ResizeDirection="Columns"/>
            <Frame Name="frmContents"
                   Source="{Binding SelectedItem.Links[0].Uri, ElementName=lstFeedItems}"
                   Grid.Column="2"
                   NavigationUIVisibility="Visible">
            </Frame>
        </Grid>
    </Grid>
</Window>

Le code-behind :

    private void btnGo_Click(object sender, RoutedEventArgs e)
    {
        using (XmlReader reader = XmlReader.Create(txtUrl.Text))
        {
            SyndicationFeed feed = SyndicationFeed.Load(reader);
            lstFeedItems.ItemsSource = feed.Items;
        }
    }

Et voilà le résultat !

Capture d'écran

5 Comments

  1. Bolux says:

    Bonjour,

    Très intéressant comme article c”est exactement ce que je recherchais !

    Je souhaiterais savoir si vous pourriez m”envoyer le code source du programme que vous avez créé sur le screenshot en fin d”article ?

    Merci d”avance, cordialement .

    • Bonjour Bolux,

      Malheureusement je ne crois pas avoir gardé les sources, c”était du code “jetable” écrit juste pour l”occasion. Mais normalement tout est dans l”article… Le code manquant est celui qui est généré automatiquement par Visual Studio et que je n”ai pas recopié ici.

      Cordialement,
      Thomas

  2. Bolux says:

    Merci bien . Coridalement

  3. Vespira says:

    Bonjour,

    Il semble que Bolux soit un aficionado de la corida 😀

    Je voulais te demander si tu savais comment afficher l’arbre de contenu d’un objet de type SyndicationFeed ? J’ai écrit une méthode qui ne semble pas fonctionner :

    private string ObjectToXml(object input)
    {
    string outputXmlString;

    System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(input.GetType());
    using (System.IO.StringWriter sw = new System.IO.StringWriter())
    {
    try
    {
    xs.Serialize(sw, input);
    outputXmlString = sw.ToString();
    }
    catch (Exception ex)
    {
    outputXmlString = ex.ToString();
    }
    }

    return outputXmlString;
    }

    Je voudrais vérifier les champs disponibles pour plusieurs sources RSS, et je m’écorche le visage quand je vois que chaque site renvoie du XML à sa sauce ! Des champs mal utilisés (titre dans Id, lien dans description, …), des champs pas utilisés d’autres oui, …

    Bref c’est un souk monstrueux, digne de effervescence d’un Black Friday sur une surface de 30m². Merci beaucoup d’avance

    • Thomas Levesque says:

      Effectivement, il y a au moins deux principaux formats pour la syndication de contenu (RSS et Atom), et en plus toutes les implémentations n’utilisent pas exactement les mêmes champs pour la même chose… Malheureusement je ne pense pas qu’il y ait une solution miracle, il faut utiliser des heuristiques (par exemple, si le champ title n’est pas renseigné, chercher le titre dans le champ id ou toto, etc).

      Pour ce qui est de la représentation, je ne vois pas très bien ce que tu veux dire… Si le but est d’examiner le flux RSS pour voir quels champs sont utilisés, le plus simple est probablement d’utiliser un éditeur XML, en reformatant automatiquement si besoin.

Leave a comment

css.php