Раньше не занимался сериализацией объектов. Нужна сериализация в XML. С наскоку хотел победить, но что-то не срослось.. ((
Посоветуйте книжку/статьи.
Интересуют нетривиальные (ну для меня нетривиальные на данном этапе) случаи.
Например сериализовать коллекцию интрефейсов, типа:
public class Data
{
public SomeCollection Elements{ get; set;}
public class SomeCollection: ObservableCollection<IElement>{}
}
public interface IElement
{
string Title{get;set;}
}
public class ElementA : IElement
{
...
}
public class ElementB : IElement
{
...
}
Контроль процесса сериализации производных классов, типа
Вариант 1 (и самый простой)
Использовать XmlSerializer и атрибуты из System.Xml.Serialization (XmlArrayAttribute, XmlElementAttribute и т.п.)
Однако, в вашем случае вряд ли подойдет, т.к. имеют место быть ограничения на сериализацию (в части коллекций, например)
Вариант 2
Явно реализовать в классах IXmlSerializable.
Здравствуйте, RushDevion, Вы писали:
RD>Вариант 1 (и самый простой) RD>Использовать XmlSerializer и атрибуты из System.Xml.Serialization (XmlArrayAttribute, XmlElementAttribute и т.п.) RD>Однако, в вашем случае вряд ли подойдет, т.к. имеют место быть ограничения на сериализацию (в части коллекций, например)
RD>Вариант 2 RD>Явно реализовать в классах IXmlSerializable.
RD>Вариант 3 RD>Написать свой сериализатор
Пасиб за ответ)
Я просто немного подзапутался с походами. через установку атрибутов (способ 1), через реализцию IXmlSerializable (чета пока вообще темный лес для мну).
Как раз хотелось бы литературы, в которой были бы освещены вопросы. Посидеть, почитать. Чтобы база была. С наскоку можно решить, написать чтонить на скорую руку, вообще можно топорно методы реализовать методы в самих классах XmlElement SaveXML(), LoadXML(XmlElement element).
Хотелось бы сделать правильно, чтобы обойти грабли и сразу в дамки)) Поэтому здесь и задал вопрос, ведь люди тут весьма опытные сидят.
Здравствуйте, WSN, Вы писали:
WSN>Раньше не занимался сериализацией объектов. Нужна сериализация в XML. С наскоку хотел победить, но что-то не срослось.. (( WSN>Посоветуйте книжку/статьи. WSN>Интересуют нетривиальные (ну для меня нетривиальные на данном этапе) случаи. WSN>Например сериализовать коллекцию интрефейсов, типа:
… WSN>Сижу, гуглю, разбираюсь, жду ответов ))
Поглядим) Просто когда гуглишь чтонить типа xml+serialization выводится такой объем информации, что дрюкнуться можно)
Ну и как-то кусками вырывать.. этот подход имеет право на жизнь, часто пользуюсь.. Но в некоторых аспектах хотелось бы разобарться детально.
В свое время наткнулся на книжку по XSLT, врубился очень резво. потом к сожелению, потерял название, до сих пор жалею. Когда надо было, обращался к другим книжкам по XSLT, написано так беззубо бывает, что только путает. Вообщем, справочник есть справочник. А грамотная подача информации.. это совсем другое. ))
В любом случае спасибо за ссылку , должна помочь)
public abstract class GroupBase: IXmlSerializable
{
public abstract object GetValue(DOMElement element);
private GroupFilterCollection _filters;
public GroupFilterCollection Filters
{
get
{
if (_filters == null)
_filters = new GroupFilterCollection();
return _filters;
}
}
public class GroupFilterCollection : ObservableCollection<IFilter>, IXmlSerializable { ... }
public void WriteXml(System.Xml.XmlWriter writer)
{
// Насколько понял
writer.WriteStartElement("GroupBase");
Filters.WriteXml(writer);
writer.WriteEndElement();
}
}
public class GroupByName : GroupBase
{
public override object GetValue(DOMElement element) { ... }
public string SomeString {get; set;}
// Как мне сделать чтобы имя элемента было GroupByName: writer.WriteStartElement("GroupByName");
// Но при этом была базовым классом записана информация о фильтрах ??
}
Для кода на шарпе кошернее использовать тег [c#] или [cs]
// Как мне сделать чтобы имя элемента было GroupByName: writer.WriteStartElement("GroupByName");
// Но при этом была базовым классом записана информация о фильтрах ??
WSN>Или я чтото не так понял?
Не вижу, что общего тут со стартовым вопросом А, например, имя для элемента групп можно как-то передавать в наследника. Или посредством виртуального или обычного свойства или с помощью атрибута — смотря от чего должно зависеть значение.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Не вижу, что общего тут со стартовым вопросом А, например, имя для элемента групп можно как-то передавать в наследника. Или посредством виртуального или обычного свойства или с помощью атрибута — смотря от чего должно зависеть значение.
Да, я не дописал пост) одно дело да, имя элемента можно так сделать.. другое дело в производном классе есть свойство SomeString.
надо чтобы базовый класс сериализовал коллекцию фильтров, а производный добавил описание для свойства SomeString.
Насчет виртуальности.. хм.. может это можно решить объявив в базовом классе метод типа
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement(GetElementName());
Filters.WriteXml(writer);
WriteExtraSerialization(writer);
writer.WriteEndElement();
}
Так?
_FR>Для кода на шарпе кошернее использовать тег [c#] или [cs]
Исправился. Теперь будет усе кашерно) а чем отступы расставлять.. запаривает пробелы жать (по табу упрыгивает) ((
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, WSN, Вы писали:
WSN>>Насчет виртуальности.. хм.. может это можно решить объявив в базовом классе метод типа _FR>
_FR>Нет, это излишне. Мне казалось, что нужно только имя тега настраивать из базы.
_FR>Лучше сделай свой аттрибут, навесь его на базу со значением "GroupBase", а на наследника с "GroupByName".
Я честно говоря так и не смог понять, что для Вас важнее,
получить в итоге XML нужного формата или иметь возможность сериализовать свои фильтры в XML.
Если последнее, то, наверное самое простое решение будет таким:
[XmlRootAttribute( "storage" )]
public sealed class FiltersStorage
{
[XmlArray( "filters" )]
[XmlArrayItem( typeof( GroupById ) )]
[XmlArrayItem( typeof( GroupByName ) )]
//И так далее перечисляем свои типыpublic List<GroupBase> Filters { get;set; }
}
//И сериализация предельно простая var ser = new XmlSerializer(typeof(FiltersStorage));
ser.Serialize(...);
ser.Deserialize(...);
Здравствуйте, RushDevion, Вы писали:
RD>получить в итоге XML нужного формата или иметь возможность сериализовать свои фильтры в XML.
Вообщем-то хотелось бы контролировать сериализацию, потому что выходной xml явлется грубо говоря конфигурационным файлом. И его можно менять извне.
RD>
RD>[XmlRootAttribute( "storage" )]
RD>public sealed class FiltersStorage
RD>{
RD> [XmlArray( "filters" )]
RD> [XmlArrayItem( typeof( GroupById ) )]
RD> [XmlArrayItem( typeof( GroupByName ) )]
RD> //И так далее перечисляем свои типы
RD> public List<GroupBase> Filters { get;set; }
RD>}
RD>//И сериализация предельно простая
RD>var ser = new XmlSerializer(typeof(FiltersStorage));
RD>ser.Serialize(...);
RD>ser.Deserialize(...);
RD>
Ну.. я дошел уже до этого. Но вот мне интересно другое. Если моей библиотекой будут пользоваться сторонние организации и создавать собственные типы группировок, наследуясь от абстрактного GroupBase. Как тогда им добавлять описания в FiltersStorage ?
Re: Сериализация в XML
От:
Аноним
Дата:
11.03.10 06:26
Оценка:
Здравствуйте, WSN, Вы писали:
WSN>Здравствуйте!
WSN>Раньше не занимался сериализацией объектов. Нужна сериализация в XML. С наскоку хотел победить, но что-то не срослось.. (( WSN>Посоветуйте книжку/статьи. WSN>Интересуют нетривиальные (ну для меня нетривиальные на данном этапе) случаи. WSN>Например сериализовать коллекцию интрефейсов, типа:
Догадка сделанная в этой статье относительно implicit type cast очень мне помогла в свое время. Язык очень простой и доходчивый.
Re[2]: Сериализация в XML
От:
Аноним
Дата:
11.03.10 08:08
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, WSN, Вы писали:
WSN>>Здравствуйте!
WSN>>Раньше не занимался сериализацией объектов. Нужна сериализация в XML. С наскоку хотел победить, но что-то не срослось.. (( WSN>>Посоветуйте книжку/статьи. WSN>>Интересуют нетривиальные (ну для меня нетривиальные на данном этапе) случаи. WSN>>Например сериализовать коллекцию интрефейсов, типа:
А>Вот ссылка на статью, где неплохо изложены некоторые проблемы и как их относительно красиво решать: http://www.codeproject.com/KB/XML/xmlserializerforunknown.aspx
А>Догадка сделанная в этой статье относительно implicit type cast очень мне помогла в свое время. Язык очень простой и доходчивый.
Еще момент, на который стоит обратить внимание... ТаймСпэны XmlSerializer не сериализует (хотя форматтеру тип известен). Для вашего случая, полагаю, XmlSerializer — это лучшее решение (сериализовать вручную, полагаю вредным по многим причинам). Но есть другие "стандарные" средства: Binary и Soap Formatter.
Здравствуйте, Аноним, Вы писали:
А>Вот ссылка на статью, где неплохо изложены некоторые проблемы и как их относительно красиво решать: http://www.codeproject.com/KB/XML/xmlserializerforunknown.aspx
А>Догадка сделанная в этой статье относительно implicit type cast очень мне помогла в свое время. Язык очень простой и доходчивый.
Статейка хорошая, пошел по этому пути..
Только вот не столкнулся с парой камней..
public abstract class A : IXmlSerializable
{
public abstract object SomeAbstractMethod()
#region Properties
...
#endregion
ReadXml, WriteXml and GetSchema() - реализую вручную
}
public sealed class B : A
{
public object SomeAbstractMethod(){ return null;}
[XmlAttribute(AttributeName = "SomeString")]
public string SomeString{get;set;}
}
public sealed class C : A
{
public object SomeAbstractMethod(){ return 1;}
//Вообще никаких свойств, только реализация абстрактного метода.
}
В надежде, что мне не придется снова писать тройку ReadXml, WriteXml and GetSchema для простого класса, который добавляет всего одно свойство я добавил для класса В
[XmlAttribute(AttributeName = "SomeString")]
Мои ожидания не оправдались. В итоге почему-то атрибут не добавился..
это первый камень.
Второй камень:
Решил сериализовать класс С.
В итоге сериализовалось, но добавился какой-то дикий namespace к элементу.
Посоветуйте, как избавиться от камней ))
Как-только все заработает, отпишу результат моих исканий))