尝试解析plist文档时出现NotSupportedException

时间:2011-08-02 08:41:32

标签: xml linq-to-xml windows-phone

我目前正在为我工​​作的公司开发Windows Phone 7应用程序。对于配置部分,我想分享用于我们的iPhone应用程序并存储在plist文件中的远程服务器上的配置。

我使用System.Xml.Linq.XDocumentParse我使用WebClient实例下载的字符串。

这是代码:

        Uri plistLocation = new 
            Uri(@"http://iphonevnreporter.vol.at/Settings.bundle/mw_test.plist");
        WebClient client = new WebClient();

        try
        {
            client.DownloadStringCompleted += ((sender,e) => {
                if (e.Error == null)
                {
                    XDocument xdoc = XDocument.Parse(e.Result);

                    //XElement element = XElement.Parse(e.Result.ToString());
                    var dictItems = xdoc.Descendants("dict");
                    foreach (XElement elem in dictItems)
                    {
                    }
                }
            });
        }
        catch (Exception e)
        {
        }
        client.DownloadStringAsync(plistLocation);

在此示例中,plist在根dict元素下只有一个plist元素,但我收到了NotSupportedException。异常发生在XDocument.Parse(e.Result)

这是StackTrace:

   at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.Linq.XDeclaration..ctor(XmlReader r)
   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 VorarlbergOnline.MainViewModel.<FillSections>b__10(
                 Object sender, DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.OnDownloadStringCompleted
            (DownloadStringCompletedEventArgs     e)
   at System.Net.WebClient.DownloadStringOperationCompleted(Object arg)
   at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext 
        executionContext,     ContextCallback callback, Object state)
   at System.Threading.ThreadPool.WorkItem.doWork(Object o)
   at System.Threading.Timer.ring()

加载其他XML文件工作正常,因此代码似乎没问题。我检查引用的dtd是否可能是问题,但它加载正常。所以我现在有点想法了。

2 个答案:

答案 0 :(得分:5)

好的,现在我实际上是通过浏览器查看文件,而不是通过浏览器,我确定这是问题所在:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

看起来像Windows Phone 7中不支持doctype解析。你可以做一个快速而又脏的黑客来删除它:

string xml = e.Result;
int docTypeIndex = xml.IndexOf("<!DOCTYPE");
if (docTypeIndex != -1)
{
    int docTypeEnd = xml.IndexOf(">", docTypeIndex);
    // TODO: Decide what to do if docTypeEnd is -1...
    xml = xml.Substring(0, docTypeIndex) + xml.Substring(docTypeEnd + 1);
}

答案 1 :(得分:4)

问题实际上是DOCTYPE,在Windows Phone上无法由XDocument解析。更短的解决方案是使用Regex删除DOCTYPE引用:

string replaced = Regex.Replace(e.Result, "<!DOCTYPE.+?>", string.Empty);
XDocument.Parse(replaced);