我想检测一个Feed是否发生了变化,我能想到的唯一方法就是散列xml文档的内容并将其与feed的最后一个哈希值进行比较。
我正在使用XmlReader,因为SyndicationFeed使用它,所以理想情况下我不想加载联合供稿,除非供稿已更新。
XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed");
SyndicationFeed feed = SyndicationFeed.Load(reader);
答案 0 :(得分:3)
为什么不检查Feed的LastUpdatedTime?这是一种内置的方式来告诉你某些东西是否是新东西。您只需跟踪LastUpdatedTime并定期将其与最新的LastUpdatedTime进行比较,而不是散列和存储哈希值:
using System;
using System.ServiceModel.Syndication;
using System.Xml;
public class MyClass
{
private static DateTime _lastFeedTime = new DateTime(2011, 10, 10);
public static void Main()
{
XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed");
SyndicationFeed feed = SyndicationFeed.Load(reader);
if (feed.LastUpdatedTime.LocalDateTime > _lastFeedTime)
{
_lastFeedTime = feed.LastUpdatedTime.LocalDateTime;
// load feed...
}
}
}
答案 1 :(得分:3)
如果你真的想要哈希方式,你可以做以下事情:
var client = new WebClient();
var content = client.DownloadData("http://www.extremetech.com/feed");
var hash = MD5.Create().ComputeHash(content);
var hashString = Convert.ToBase64String(hash);
// you can then compare hashes and if changed load it this way
XmlReader reader = XmlReader.Create(new MemoryStream(content));
当然,通过这种方式,你会发现内容的任何变化,即使是最轻微的。
恕我直言最好的方法是加载Feed无论如何只是散列文章的内容,你可以散列这样的字符串:
var toHash = "string to hash";
var hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(toHash);
var hashString = Convert.ToBase64String(hash);
希望这有帮助。
答案 2 :(得分:2)
哈希方法在这种情况下不起作用,因为某些服务器端缓存添加了XML注释,即使实际的Feed从未发生变化,也经常非常频繁。
对于此Feed,您可以执行的一项操作是使用HTTP条件请求,要求服务器仅在您自上次请求后实际修改数据时才为您提供数据。
例如:
您有一个全局/成员变量来保存Feed中的最后修改日期时间
var lastModified = DateTime.MinValue;
然后每次你提出如下的请求
var request = (HttpWebRequest)WebRequest.Create( "http://www.extremetech.com/feed" );
request.IfModifiedSince = lastModified;
try {
using ( var response = (HttpWebResponse)request.GetResponse() ) {
lastModified = response.LastModified;
using ( var stream = response.GetResponseStream() ) {
//*** parsing the stream
var reader = XmlReader.Create( stream );
SyndicationFeed feed = SyndicationFeed.Load( reader );
}
}
}
catch ( WebException e ) {
var response = (HttpWebResponse)e.Response;
if ( response.StatusCode != HttpStatusCode.NotModified )
throw; // rethrow an unexpected web exception
}