Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Вопрос по десериализаци


Автор: nvb 27.11.2012, 15:42
Господа, прокомментируйте, пжст, вот какой момент.

В коде один из пользовательских типов заполняется из xml следующим образом:
Код

            XmlDocument document = new XmlDocument();
            document .LoadXml(incomingXml);
            XPathNavigator navigator = doc.CreateNavigator()
            XPathNavigator routingNav = navigator.SelectSingleNode("looking for that it is necessary", namespace);
            XmlSerializer s = new XmlSerializer(typeof(MyType));
            using (StringReader r = new StringReader(routingNav.OuterXml))
            {
                using (XmlReader reader = XmlReader.Create(r))
                {
                    mytype= (MyType)s.Deserialize(reader);
                }
            }



Все работает, но смущает, что использовать приходится и XPathNavigator, и StringReader, и XmlReader. Найти материалы про десериализацию, скажем, XPathNavigator напрямую не удалось. Есть ли более компактный способ десериализации?
Спасибо.

Автор: gambit 29.11.2012, 11:27
Если xml в файле

Код

internal T Get(string path)
        {
            var rqSer = new XmlSerializer(typeof(T));

            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                return (T)rqSer.Deserialize(fs);
            }
        }

        internal void Set(string path, T obj)
        {
            var rqSer = new XmlSerializer(typeof(T));
            var ns = new XmlSerializerNamespaces(); // эта и след строка нужны, что бы выкинуть пространства имен
            ns.Add(string.Empty, string.Empty);     // если они нужны или не мешают, то эти строки можно затереть и выпилить ns из сериализации

            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                rqSer.Serialize(fs, obj, ns);
            }
        }


Если xml в строке

Код

        public T Get(string xml)
        {
            var rqSer = new XmlSerializer(typeof(T));

            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                using (var sw = new StreamReader(stream))
                {
                    return (T)rqSer.Deserialize(sw);
                }
            }
        }

        public string Set(T obj)
        {
            var rqSer = new XmlSerializer(typeof(T));
            var ns = new XmlSerializerNamespaces();
            ns.Add(string.Empty, string.Empty);

            using (var stream = new MemoryStream())
            {
                using (var sReader = new StreamReader(stream))
                {
                    rqSer.Serialize(stream, obj, ns);
                    sReader.BaseStream.Position = 0;
                    return sReader.ReadToEnd();
                }
            }
        }


Добавлено @ 11:29
Упс. Не дочитал вопрос видимо или не понял. Но в любом случае, мне кажется, лучше сначала  весь объект десериализовать, потом из него нужное выбирать. Так что эти самые короткие варианты десериализации не совсем мимо)

Добавлено @ 11:32
Ну да, по всей видимости недопонял сути. Я так понимаю, что дан некий файл, в нем мы выбираем конкретную ноду и десериализуем только ее.
Выражу имхо, мне кажется, если нода одна, ее проще регуляркой вытащить, чем XPathNavigator, а если их много, то проще сначала весь xml распакавать и работать с ним как с объектом

Автор: nvb 30.11.2012, 09:33
Цитата(gambit @ 29.11.2012,  11:27)
Если xml в файле

Код

internal T Get(string path)
        {
            var rqSer = new XmlSerializer(typeof(T));

            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                return (T)rqSer.Deserialize(fs);
            }
        }

        internal void Set(string path, T obj)
        {
            var rqSer = new XmlSerializer(typeof(T));
            var ns = new XmlSerializerNamespaces(); // эта и след строка нужны, что бы выкинуть пространства имен
            ns.Add(string.Empty, string.Empty);     // если они нужны или не мешают, то эти строки можно затереть и выпилить ns из сериализации

            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                rqSer.Serialize(fs, obj, ns);
            }
        }


Если xml в строке

Код

        public T Get(string xml)
        {
            var rqSer = new XmlSerializer(typeof(T));

            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                using (var sw = new StreamReader(stream))
                {
                    return (T)rqSer.Deserialize(sw);
                }
            }
        }

        public string Set(T obj)
        {
            var rqSer = new XmlSerializer(typeof(T));
            var ns = new XmlSerializerNamespaces();
            ns.Add(string.Empty, string.Empty);

            using (var stream = new MemoryStream())
            {
                using (var sReader = new StreamReader(stream))
                {
                    rqSer.Serialize(stream, obj, ns);
                    sReader.BaseStream.Position = 0;
                    return sReader.ReadToEnd();
                }
            }
        }


Добавлено @ 11:29
Упс. Не дочитал вопрос видимо или не понял. Но в любом случае, мне кажется, лучше сначала  весь объект десериализовать, потом из него нужное выбирать. Так что эти самые короткие варианты десериализации не совсем мимо)

Добавлено @ 11:32
Ну да, по всей видимости недопонял сути. Я так понимаю, что дан некий файл, в нем мы выбираем конкретную ноду и десериализуем только ее.
Выражу имхо, мне кажется, если нода одна, ее проще регуляркой вытащить, чем XPathNavigator, а если их много, то проще сначала весь xml распакавать и работать с ним как с объектом

ну можно и так, но относится ли Matches к десеарилуемым? с ним-то что потом делать?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)