2011-02-07 108 views
4

wtih意見,我嘗試加載一個XML文件,使用此代碼:煩惱XmlSerialzier

XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject)); 
StreamReader reader = new StreamReader(fileName); 
object myobject = xmlSerializer.Deserialize(reader); 

當文件中包含這樣的評論:

<?xml version="1.0" encoding="utf-8"?> 
<!-- edited with XMLSpy v2007 sp2 --> 
<route> 
    <!--File created on 26-Nov-2010 12:36:42--> 
    <file_content>1 
    <!--0 = type1 ; 1 = type2--> 
    </file_content> 
</route> 

的XmlSerializer返回類似

錯誤

意外的節點類型註釋。 ReadElementString方法只能在簡單或空內容的元素上調用

當我刪除文件中的這個註釋時,它工作正常。

我不知道問題出在哪裏,有什麼想法?

+0

您可以嘗試將註釋放在元素內嗎?我認爲xml解析器需要將第一個節點作爲根元素 – 2011-02-07 08:48:08

+0

對不起,但我沒有決定文件格式,它來自提供者,而我正在試圖解析他的格式沒有改變。 – Dav 2011-02-07 08:52:36

回答

4

正如你所看到的,在序列化的XML中不允許註釋,但這對你來說應該沒有問題。你可能無法控制源的XML,但你控制反序列化過程,所以索性反序列化之前刪除所有留言:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(myobject)); 

    // load document 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(filename); 

    // remove all comments 
    XmlNodeList l = doc.SelectNodes("//comment()"); 
    foreach (XmlNode node in l) node.ParentNode.RemoveChild(node); 

    // store to memory stream and rewind 
    MemoryStream ms = new MemoryStream(); 
    doc.Save(ms); 
    ms.Seek(0, SeekOrigin.Begin); 

    // deserialize using clean xml 
    xmlSerializer.Deserialize(XmlReader.Create(ms)); 

如果你的對象是巨大的,你反序列化它們的數量龐大的在短短吼,我們可以研究一些框架外的快速Xpath讀取器。

2

我同意@mmix,你必須在嘗試序列化它之前刪除註釋。

可能是另一種方式來刪除註釋,可以使用XmlReader與​​

public static T DeSerialize<T>(string filePath) 
    { 
     var x = new XmlSerializer(typeof (T)); 

     //Serilaize would fail if there are comments in the xml document 
     var xmlReaderSettings = new XmlReaderSettings {IgnoreComments = true}; 
     var xmlReader = XmlReader.Create(filePath, xmlReaderSettings); 

     return (T)x.Deserialize(xmlReader); 
    } 
0

我找到jacob aloysious該問題的最優雅的答案。當使用System.ServiceModel.SyndicationFeed.Load函數讀取RSS源時,它也可以工作。示例如下:

public SyndicationFeed GetFeed(String url) 
{ 
    var request = (HttpWebRequest)WebRequest.Create(url); 
    using (var response = request.GetResponse()) 
    using (var responseStream = response.GetResponseStream()) 
    { 
     Debug.Assert(responseStream != null, "responseStream != null"); 

     var xmlReaderSettings = new XmlReaderSettings { IgnoreComments = true }; 
     using (XmlReader xmlReader = XmlReader.Create(responseStream, xmlReaderSettings)) 
     { 
      var feed = SyndicationFeed.Load(xmlReader); 
      return feed; 
     } 
    } 
}