在Xml Serializer中带有注释的麻烦

时间:2011-02-07 08:32:03

标签: c# .net-4.0 xmlserializer xml-comments

我尝试使用以下代码加载XML文件:

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方法

当我在文件中删除此评论时,它可以正常工作。

我不知道问题出在哪里,有什么想法吗?

3 个答案:

答案 0 :(得分:5)

正如您所看到的,序列化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读取器。

答案 1 :(得分:2)

我同意@mmix,您必须在尝试序列化之前删除评论。

可能是删除评论的另一种方法,可能是XmlReaderXmlReaderSettings一起使用

    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);
    }

答案 2 :(得分: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;
        }
    }
}