XDocument.在Windows Phone 7中解析不同

本文关键字:Windows Phone XDocument | 更新日期: 2023-09-27 17:54:13

我在WP7应用程序和c# 3.5应用程序中运行完全相同的代码。WP7应用程序在调用XDocument.Parse()时抛出NotSupportedException,而c# 3.5应用程序解析XML没有问题。下面是使用的代码:

WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadThreadsComplete);
client.DownloadStringAsync(new Uri("http://us.battle.net/sc2/en/forum/40568/", UriKind.Absolute));
...
private static void DownloadThreadsComplete(object sender, DownloadStringCompletedEventArgs e)
{
    var doc = XDocument.Parse(e.Result);
}

知道为什么会这样吗?奇怪的是,当试图解析一个SC2论坛时,它失败了,而一个WoW论坛工作得很好(http://us.battle.net/wow/en/forum/984270/)。

编辑:

异常消息为"NotSupportedException"。下面是完整的堆栈跟踪:

   at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options)
   at System.Xml.Linq.XDocument.Parse(String text, LoadOptions options)
   at System.Xml.Linq.XDocument.Parse(String text)
   at SC2ForumReader.Pages.ForumViewerPage.DownloadThreadsComplete(Object sender, DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.OnDownloadStringCompleted(DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.DownloadStringOperationCompleted(Object arg)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Delegate.DynamicInvokeOne(Object[] args)
   at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
   at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
   at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
   at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
   at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

Edit2:

我已经按照建议做了,并查看了2个不同请求的输出。此外,在我的3.5客户端应用程序中,我强制用户代理与WP7模拟器中的用户代理相同,以确保它不是导致问题的用户代理。

下面是从Visual Studio复制的doctype声明:

<!DOCTYPE html PUBLIC '"-//W3C//DTD XHTML 1.1//EN'" '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'">

文档类型在每个文档中都是相同的,但是在文件中有一些明显的差异(看起来在3.5侧插入了一些额外的字符):

WP7 Emulator: StarCraft II

3.5应用:StarCraft II

XDocument.在Windows Phone 7中解析不同

问题是XDocument。Parse启用DTD处理(默认情况下,XmlTextReader通常禁用此处理),但它不提供解析器。试试下面的代码:

private static void DownloadThreadsComplete(object sender, DownloadStringCompletedEventArgs e)
{
    XDocument doc;
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.DtdProcessing = DtdProcessing.Ignore;
    using (XmlReader reader = XmlReader.Create(new StringReader(e.Result), settings))
    {
         doc = XDocument.Load(reader);
    }
    // Do stuff with doc
}

或:-

private static void DownloadThreadsComplete(object sender, DownloadStringCompletedEventArgs e)
{
    XDocument doc;
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.DtdProcessing = DtdProcessing.Parse;
    settings.XmlResolver = new XmlPreloadedResolver(XmlKnownDtds.Xhtml10);
    using (XmlReader reader = XmlReader.Create(new StringReader(e.Result), settings))
    {
         doc = XDocument.Load(reader);
    }
    // Do stuff with doc
}