Объединение двух SyndicationFeeds - PullRequest
       14

Объединение двух SyndicationFeeds

10 голосов
/ 17 сентября 2008

Какой простой способ объединить feed и feed2 ? Я хочу, чтобы элементы из feed2 были добавлены в feed . Также я хочу избежать дубликатов, поскольку feed может уже содержать элементы, если вопрос помечен как WPF, так и Silverlight.

Uri feedUri = new Uri("http://stackoverflow.com/feeds/tag/silverlight");
XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri);
SyndicationFeed feed = SyndicationFeed.Load(reader);    

Uri feed2Uri = new Uri("http://stackoverflow.com/feeds/tag/wpf");
XmlReader reader2 = XmlReader.Create(feed2Uri.AbsoluteUri);
SyndicationFeed feed2 = SyndicationFeed.Load(reader2);

Ответы [ 6 ]

11 голосов
/ 17 сентября 2008

Вы можете использовать LINQ, чтобы упростить код для объединения двух списков (не забудьте указать System.Linq в ваших целях и, если необходимо, ссылаться на System.Core в вашем проекте). Здесь находится Main, который выполняет объединение и печатает их в консоль (при правильной очистке ридера).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.ServiceModel.Syndication;

namespace FeedUnion
{
    class Program
    {
        static void Main(string[] args)
        {
            Uri feedUri = new Uri("http://stackoverflow.com/feeds/tag/silverlight"); 
            SyndicationFeed feed;
            SyndicationFeed feed2;
            using(XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri))
            {
                feed= SyndicationFeed.Load(reader); 
            }
            Uri feed2Uri = new Uri("http://stackoverflow.com/feeds/tag/wpf"); 
            using (XmlReader reader2 = XmlReader.Create(feed2Uri.AbsoluteUri))
            {
            feed2 = SyndicationFeed.Load(reader2);
            }
            SyndicationFeed feed3 = new SyndicationFeed(feed.Items.Union(feed2.Items));
            StringBuilder builder = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(builder))
            {
                feed3.SaveAsRss20(writer);
                System.Console.Write(builder.ToString());
                System.Console.Read();
            }
        }
    }
}
1 голос
/ 17 сентября 2008

Ну, одна из возможностей - создать новый синдикационный канал, который является клоном первого канала, а затем просто перебрать каждый пост во втором, проверить первый на наличие и добавить его, если он есть.

Что-то вроде:

SyndicationFeed newFeed = feed.clone;
foreach(SyndicationItem item in feed2.items)
{
  if (!newFeed.contains(item))
    newFeed.items.Add(item);
}

может быть в состоянии сделать это. Похоже, что 'items' - это простой перечисляемый список синдикационных предметов, поэтому нет причины, по которой вы не можете просто добавить их.

0 голосов
/ 06 февраля 2016

Для меня это работало нормально:

// create temporary List of SyndicationItem's
List<SyndicationItem> tempItems = new List<SyndicationItem>();

// add all feed items to the list
tempItems.AddRange(feed.Items);
tempItems.AddRange(feed2.Items);

// remove duplicates with Linq 'Distinct()'-method depending on yourattributes

// add list without duplicates to 'feed2'
feed2.Items = tempItems
0 голосов
/ 29 июля 2013
        //Executed and Tested :)            
        using (XmlReader reader = XmlReader.Create(strFeed))
        {
            rssData = SyndicationFeed.Load(reader);
            model.BlogFeed = rssData; ;
        }
        using (XmlReader reader = XmlReader.Create(strFeed1))
        {
            rssData1 = SyndicationFeed.Load(reader);
            model.BlogFeed = rssData1;
        }

        SyndicationFeed feed3 = new SyndicationFeed(rssData.Items.Union(rssData1.Items));
        model.BlogFeed = feed3;           
        return View(model);
0 голосов
/ 18 января 2012

Я превратил принятый сегодня ответ в юнит-тест, просто чтобы немного изучить это:

    [TestMethod]
    public void ShouldCombineRssFeeds()
    {
        //reference: /61674/obedinenie-dvuh-syndicationfeeds

        SyndicationFeed feed;
        SyndicationFeed feed2;

        var feedUri = new Uri("http://stackoverflow.com/feeds/tag/silverlight");
        using(var reader = XmlReader.Create(feedUri.AbsoluteUri))
        {
            feed = SyndicationFeed.Load(reader);
        }

        Assert.IsTrue(feed.Items.Count() > 0, "The expected feed items are not here.");

        var feed2Uri = new Uri("http://stackoverflow.com/feeds/tag/wpf");
        using(var reader2 = XmlReader.Create(feed2Uri.AbsoluteUri))
        {
            feed2 = SyndicationFeed.Load(reader2);
        }

        Assert.IsTrue(feed2.Items.Count() > 0, "The expected feed items are not here.");

        var feedsCombined = new SyndicationFeed(feed.Items.Union(feed2.Items));

        Assert.IsTrue(
            feedsCombined.Items.Count() == feed.Items.Count() + feed2.Items.Count(),
            "The expected number of combined feed items are not here.");

        var builder = new StringBuilder();
        using(var writer = XmlWriter.Create(builder))
        {
            feedsCombined.SaveAsRss20(writer);
            writer.Flush();
            writer.Close();
        }

        var xmlString = builder.ToString();

        Assert.IsTrue(new Func<bool>(
            () =>
            {
                var test = false;

                var xDoc = XDocument.Parse(xmlString);
                var count = xDoc.Root.Element("channel").Elements("item").Count();
                test = (count == feedsCombined.Items.Count());

                return test;
            }
        ).Invoke(), "The expected number of RSS items are not here.");
    }
0 голосов
/ 17 сентября 2008

Если это только для стекового потока, вы можете использовать это:
https://stackoverflow.com/feeds/tag/silverlight%20wpf
Это будет объединять два тега.

Для более общего решения я не знаю. Возможно, вам придется вручную перебирать элементы двух каналов и объединять их вместе. Вы можете сравнить элементов s, чтобы увидеть, являются ли они дубликатами.

...