Проблемы с комментариями в XmlSerialzier - PullRequest
5 голосов
/ 07 февраля 2011

Я пытаюсь загрузить файл 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 ]

5 голосов
/ 07 февраля 2011

Как вы можете видеть, комментарии не разрешены в сериализованном 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 голосов
/ 24 июля 2014

Я согласен с @mmix, вам придется удалить комментарии, прежде чем пытаться его сериализовать.

Может быть и другой способ удаления комментариев, возможно использование XmlReader с 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 голосов
/ 15 октября 2016

Я считаю jacob aloysious самым элегантным ответом на проблему. Это также работает при чтении RSS-каналов с использованием функции System.ServiceModel.SyndicationFeed.Load. Пример ниже:

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