嘗試讀取某些 DateTime 格式時,RSS20FeedFormatter 會引發例外狀況
本文提供 System.Xml.XmlException
使用 SyndicationFeed.Load
方法從 RSS 來源讀取日期格式的相關資訊。
原始產品版本: Microsoft .NET Framework
原始 KB 編號: 2020488
徵狀
當您使用 SyndicationFeed.Load
方法從 RSS 來源讀取時,可能會收到類似下列的錯誤訊息:
System.Xml.Xml例外狀況:第7行第7列的錯誤47。 分析饋送的 XML 時,發生錯誤。 如需詳細資訊,請參閱內部例外狀況。
字串未被識別為有效的 DateTime。
其他摘要功能可能會正確地進行其他摘要的功能。
原因
因為摘要中所用的日期格式,就會發生此問題。 SyndicationFeed.Load
方法期望接收標準格式的饋送。 以下是標準格式的範例:
Mon, 05 Oct 2009 08:00:06 GMT
不過,有些摘要會使用不同的格式。 例如,有些摘要可能使用下列格式:
Wed Oct 07 08:00:07 GMT 2009
解決方案
若要解決此問題,請建立可識別不同日期格式的自訂 XML 讀取器。 以下是自訂 XML 讀取器的範例:
XmlReader r = new MyXmlReader(url);
SyndicationFeed feed = SyndicationFeed.Load(r);
Rss20FeedFormatter rssFormatter = feed.GetRss20Formatter();
XmlTextWriter rssWriter = new XmlTextWriter("rss.xml", Encoding.UTF8);
rssWriter.Formatting = Formatting.Indented;
rssFormatter.WriteTo(rssWriter);
rssWriter.Close();
class MyXmlReader : XmlTextReader
{
private bool readingDate = false;
const string CustomUtcDateTimeFormat = "ddd MMM dd HH:mm:ss Z yyyy"; // Wed Oct 07 08:00:07 GMT 2009
public MyXmlReader(Stream s) : base(s) { }
public MyXmlReader(string inputUri) : base(inputUri) { }
public override void ReadStartElement()
{
if (string.Equals(base.NamespaceURI, string.Empty, StringComparison.InvariantCultureIgnoreCase) &&
(string.Equals(base.LocalName, "lastBuildDate", StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(base.LocalName, "pubDate", StringComparison.InvariantCultureIgnoreCase)))
{
readingDate = true;
}
base.ReadStartElement();
}
public override void ReadEndElement()
{
if (readingDate)
{
readingDate = false;
}
base.ReadEndElement();
}
public override string ReadString()
{
if (readingDate)
{
string dateString = base.ReadString();
DateTime dt;
if (!DateTime.TryParse(dateString, out dt))
dt = DateTime.ParseExact(dateString, CustomUtcDateTimeFormat, CultureInfo.InvariantCulture);
return dt.ToUniversalTime().ToString("R", CultureInfo.InvariantCulture);
}
else
{
return base.ReadString();
}
}
}