结合两个 SyndicationFeed
Posted
技术标签:
【中文标题】结合两个 SyndicationFeed【英文标题】:Combining two SyndicationFeeds 【发布时间】:2010-09-09 21:38:33 【问题描述】:结合 feed 和 feed2 的简单方法是什么?我希望将 feed2 中的项目添加到 feed。我还想避免重复,因为当问题同时被 WPF 和 Silverlight 标记时,feed 可能已经有项目。
Uri feedUri = new Uri("http://***.com/feeds/tag/silverlight");
XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri);
SyndicationFeed feed = SyndicationFeed.Load(reader);
Uri feed2Uri = new Uri("http://***.com/feeds/tag/wpf");
XmlReader reader2 = XmlReader.Create(feed2Uri.AbsoluteUri);
SyndicationFeed feed2 = SyndicationFeed.Load(reader2);
【问题讨论】:
【参考方案1】:您可以使用 LINQ 简化代码以加入两个列表(不要忘记将 System.Linq 放在您的 usings 中,如果需要,请在您的项目中参考 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://***.com/feeds/tag/silverlight");
SyndicationFeed feed;
SyndicationFeed feed2;
using(XmlReader reader = XmlReader.Create(feedUri.AbsoluteUri))
feed= SyndicationFeed.Load(reader);
Uri feed2Uri = new Uri("http://***.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();
【讨论】:
LINQ 和 UNION...真是天才。我希望不要遍历提要,这符合要求。 很高兴你仍然发现它的用途:)【参考方案2】:嗯,一种可能性是创建一个新的联合提要,它是第一个提要的克隆,然后简单地遍历第二个提要上的每个帖子,检查第一个是否存在,如果不存在则添加它存在。
类似的东西:
SyndicationFeed newFeed = feed.clone;
foreach(SyndicationItem item in feed2.items)
if (!newFeed.contains(item))
newFeed.items.Add(item);
也许可以做到。看起来“项目”是一个简单的可编号的联合项目列表,所以没有理由不能简单地添加它们。
【讨论】:
我不认为一个简单的 Contains() 会做到这一点。他可能需要比较条目 ID RSS 项目元素建议有一个 guid 元素,但这不是必需的。在组合时可能需要通过首先比较 guid 来确定包含。如果 guid 不存在,请比较链接元素。可能还想与标题进行比较以确保安全。【参考方案3】:如果它只用于***,你可以使用这个:https://***.com/feeds/tag/silverlight%20wpf 这将合并两个标签。
对于更通用的解决方案,我不知道。您可能必须手动迭代两个提要的元素并将它们连接在一起。您可以比较
【讨论】:
我认为它会做 AND 而不是 OR。我想我需要合并提要。 我刚查了一下,结果是 OR 根据这篇文章,它正在执行 AND。我想我需要等待 UNION 功能才能使用 RESTFUL 标签 uri。与此同时,我需要自己迭代并手动完成。 ***.com/questions/61590/stack-overflow-tag-filtering【参考方案4】:我将今天接受的答案变成了一个单元测试,只是为了稍微探索一下:
[TestMethod]
public void ShouldCombineRssFeeds()
//reference: http://***.com/questions/79197/combining-two-syndicationfeeds
SyndicationFeed feed;
SyndicationFeed feed2;
var feedUri = new Uri("http://***.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://***.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.");
【讨论】:
【参考方案5】: //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);
【讨论】:
【参考方案6】:这对我来说很好用:
// 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
【讨论】:
以上是关于结合两个 SyndicationFeed的主要内容,如果未能解决你的问题,请参考以下文章
使用 SyndicationFeed 读取 SyndicationItem 中的非标准元素