gpt4 book ai didi

c# - 使用 C# 和 .net 3.5 阅读 RSS 的问题

转载 作者:可可西里 更新时间:2023-11-01 03:05:06 27 4
gpt4 key购买 nike

我一直在尝试编写一些例程来使用 System.ServiceModel.Syndication 中可用的新例程来读取 RSS 和 ATOM 提要,但不幸的是,Rss20FeedFormatter 在我尝试的大约一半提要上失败了,但出现以下异常:

An error was encountered when parsing a DateTime value in the XML.

只要 RSS 提要以下列格式表示发布日期,就会出现这种情况:

Thu, 16 Oct 08 14:23:26 -0700

如果 feed 将发布日期表示为 GMT,则一切顺利:

Thu, 16 Oct 08 21:23:26 GMT

如果有某种方法可以使用 XMLReaderSettings 解决这个问题,我还没有找到。有人可以帮忙吗?

最佳答案

基于 bug report to Microsoft about this 中发布的解决方法我制作了一个 XmlReader 专门用于阅读具有非标准日期的 SyndicationFeed。

下面的代码与 Microsoft 站点上的解决方法中的代码略有不同。它还需要 Oppositional's advice关于使用 RFC 1123 模式。

您需要从流创建 XmlReader,而不是简单地调用 XmlReader.Create()。我使用 WebClient 类来获取该流:

WebClient client = new WebClient();
using (XmlReader reader = new SyndicationFeedXmlReader(client.OpenRead(feedUrl)))
{
SyndicationFeed feed = SyndicationFeed.Load(reader);
....
//do things with the feed
....
}

下面是 SyndicationFeedXmlReader 的代码:

public class SyndicationFeedXmlReader : XmlTextReader
{
readonly string[] Rss20DateTimeHints = { "pubDate" };
readonly string[] Atom10DateTimeHints = { "updated", "published", "lastBuildDate" };
private bool isRss2DateTime = false;
private bool isAtomDateTime = false;

public SyndicationFeedXmlReader(Stream stream) : base(stream) { }

public override bool IsStartElement(string localname, string ns)
{
isRss2DateTime = false;
isAtomDateTime = false;

if (Rss20DateTimeHints.Contains(localname)) isRss2DateTime = true;
if (Atom10DateTimeHints.Contains(localname)) isAtomDateTime = true;

return base.IsStartElement(localname, ns);
}

public override string ReadString()
{
string dateVal = base.ReadString();

try
{
if (isRss2DateTime)
{
MethodInfo objMethod = typeof(Rss20FeedFormatter).GetMethod("DateFromString", BindingFlags.NonPublic | BindingFlags.Static);
Debug.Assert(objMethod != null);
objMethod.Invoke(null, new object[] { dateVal, this });

}
if (isAtomDateTime)
{
MethodInfo objMethod = typeof(Atom10FeedFormatter).GetMethod("DateFromString", BindingFlags.NonPublic | BindingFlags.Instance);
Debug.Assert(objMethod != null);
objMethod.Invoke(new Atom10FeedFormatter(), new object[] { dateVal, this });
}
}
catch (TargetInvocationException)
{
DateTimeFormatInfo dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
return DateTimeOffset.UtcNow.ToString(dtfi.RFC1123Pattern);
}

return dateVal;

}

}

同样,这几乎完全是从上面链接中 Microsoft 站点上发布的变通方法复制而来的。 ...除了这个对我有用,而在 Microsoft 发布的那个没有。

注意:您可能需要在类(class)开头的两个数组中进行一点自定义。根据您的非标准提要可能添加的任何无关字段,您可能需要向这些数组添加更多项目。

关于c# - 使用 C# 和 .net 3.5 阅读 RSS 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/210375/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com