2011-02-07 110 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; 
     } 
    } 
}