计算xml提要散列的最佳方法是什么?
本文关键字:最佳 方法 是什么 xml 计算 | 更新日期: 2023-09-27 18:12:09
我想检测提要是否发生了更改,我能想到的唯一方法是对xml文档的内容进行散列,并将其与提要的最后一个散列进行比较。
我使用XmlReader,因为SyndicationFeed使用它,所以理想情况下我不想加载联合提要,除非提要已经更新。
XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed");
SyndicationFeed feed = SyndicationFeed.Load(reader);
为什么不直接检查提要的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...
}
}
}
如果您真的想使用散列方式,您可以这样做:
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);
哈希方法在这种情况下不起作用,因为一些服务器端缓存不断非常频繁地添加XML注释,即使实际提要从未更改。
对于这个提要,您可以做的一件事是使用HTTP条件请求,要求服务器仅在数据自上次请求以来实际被修改时才向您提供数据。
例如:你应该有一个全局/成员变量来保存你的提要中最后修改的日期时间
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
}