关于SyndicationFeed.Load()时发生“发生分析XML 中的一个 DateTime 值时遇到错误。”异常及解决

小柊 发表于 2016年02月14日 20时03分09秒

一、问题背景

还是接了一个项目,需要用到RSS功能。

 

一开始是准备自己写一个能解析RSS的解析器的,后来发现.net Framework居然自带了一个RSS解析器SyndicationFeed。

那既然.net都提供了,那我为什么不用呢。于是我就自己写了一个只要提供RSS地址,就能帮我解析好RSS内容并输出的方法:

 

这个方法一直没啥问题,直到后来被我拿来解析搜狐的国内新闻之后,就有问题了,总是会直接输出一个长度为0的SyndicationItem数组。

 

二、问题排查

从上面的代码里,我们不难看出,如果RSS源没有问题的话,在try语句里发生错误时,会直接进入catch语句,返回一个长度为0的SyndicationItem数组。所以只要明白到底出了一个什么错,然后去修正它就好了。我在catch语句的下一行设置断点,然后再次运行。

 

我们可以看到,这时候我们捕捉到了一个XmlException异常,它提示“在行24、位置54处出现错误。分析XML中的一个DateTime值时遇到错误。”为什么就搜狐的新闻RSS会发生DateTime解析错误呢?

这个时候就要靠我们自己去找问题原因了,我们先看看其他新闻网站的RSS格式,再和搜狐新闻的RSS格式比较一下看看。

先看是凤凰新闻的:

 

然后是新浪新闻:

 

最后是出问题的搜狐新闻:

 

发现问题了吧,搜狐新闻的pubDate字段里,星期和月份是以中文表示的。

这时我相信有些.net黑就会要开始放嘲讽了:“你们的.net Framework怎么这么垃圾啊,人家中文就识别不了了?”

对于上面这样的.net黑我只能呵呵笑笑。要知道,RSS中的日期格式要求遵守RFC822规范,具体的内容我也不展开了,我就把关于日期格式这块截图放上来:

 

所以说,是搜狐新闻RSS日期不规范的锅,并不是.net Framework的锅。

 

三、解决方案

那对于这样的不规范RSS,.net就没办法了吗?当然不是,微软官方已经提供了对应的解决方案:https://support.microsoft.com/en-us/kb/2020488

我们也可以在这篇文章里看到为什么会发生解析错误的原因:

This problem occurs because of the date format that is used in the feed. The SyndicationFeed.Load method expects to receive feeds that are in standard format.

出现此问题是由于该数据源中使用的日期格式。 SyndicationFeed.Load 方法希望接收标准格式的源。

 

微软给出的官方解决方案是,重写一个XML 读取器——MyXmlReader

新建一个类,名为MyXmlReader,然后键入代码:

然后根据需要修改你这个MyXmlReader的“CustomUtcDateTimeFormat”成员值,搜狐新闻RSS中的差不多是这样的格式:

星期日, 14 二月 2016 02:16:26 +0800

对应我前几天发表的《.net 日期和时间格式字符串》里的自定义模式日期和时间格式化字符串来看,我们这边应该将“CustomUtcDateTimeFormat”成员值设置为

dddd, dd MMM yyyy HH:mm:ss zzz

好了,保存好这个类,然后回到刚刚的代码里,我们将一开始的RSSParser函数改成:

 

然后再补充一个新的RSSNonStandardParser函数,用于在RSSParser函数碰到非标准格式RSS时接手并处理这个非标准格式RSS。

 

至此,重新编译程序并运行,现在我们就可以正确的解析搜狐新闻的RSS源了。

 

四、写在最后

本来我并不准备来写这篇文章,因为这个问题在微软的官方知识库里就有具体的原因和解决方案。但是,神奇的百度竟然没有找到这篇官方知识库文章,连着翻了好几页都没有篇正常的、有关联的结果。当时就懊恼的很,以为喷上了什么很稀奇的BUG。结果后来顺手翻墙去Google上用同样的关键词去搜,微软这篇官方知识库文章就在第二位,虽然是一篇机翻的文档,但也可以切到英文原文,稍微看了一下就明白怎么处理了。

 

百度搜索结果截图:

 

谷歌搜索截图:

 

在这里,我想对各位看官啰嗦几句,作为一个程序员,不懂得Google,真的是一件非常遗憾的事情。百度这个搜索引擎,它的搜索结果就当玩笑就好,我现在也就平时生活中用用百度搜索,当然,对它的搜索结果也只是抱着“仅供参考”的态度。如果有什么问题百度找不到靠谱的答案,千万记得去Google上看看。指不定也和我这次一样呢?

 

推荐阅读:《做个环保主义的程序员

 

小柊

2016年2月14日 19:57:37

 

相关文章

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注