6

我尝试使用以下代码加载 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 方法只能在内容简单或为空的元素上调用

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

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

4

3 回答 3

6

如您所见,序列化的 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 阅读器。

于 2011-02-07T09:22:30.040 回答
3

我同意@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);
    }
于 2014-07-24T01:52:35.187 回答
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;
        }
    }
}
于 2016-10-15T17:47:07.903 回答