Troubles wtih comments in XmlSerialzier

3.2k views Asked by At

I try to load a XML file with this code:

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

When the file contains a comment like this:

<?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 returns an error like

Unexpected node type Comment. ReadElementString method can only be called on elements with simple or empty content

When I remove this comments in file it's work fine.

I donĀ“t know where is the problem, any ideas?

3

There are 3 answers

1
mmix On

As you can see comments are not allowed in the serialized XML, but this should pose no problem for you. You might not control the source XML but you control the deserialization process, so simply remove all comments prior to deserialization:

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

If your objects are huge and you deserialize a huge number of them in short span, howler, we can investigate some out-of-framework fast Xpath readers.

0
jacob aloysious On

I agree with @mmix, you will have to remove the comments before trying to serialize it.

May be another way to remove comments, could be to use XmlReader with XmlReaderSettings

    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
Alexei - check Codidact On

I find jacob aloysious the most elegant answer for the problem. It also works when reading RSS feeds using System.ServiceModel.SyndicationFeed.Load function. Example below:

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