Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.83
krupa
106 / 106 / 35
Регистрация: 13.12.2010
Сообщений: 407
#1

Сериализация/Десериализация списка объектов в XML - C#

09.07.2013, 20:44. Просмотров 2790. Ответов 6
Метки нет (Все метки)

имеется базовый класс Figure
Figure
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
 
 
namespace DCT
{
    [Serializable]
    [DataContract]
    [KnownType(typeof(Circle))]
    [System.Xml.Serialization.XmlInclude(typeof(Circle))]
    [XmlType]
    abstract public class Figure
    {
        public virtual void Draw(Graphics g)
        { }
        public string Name;
        public virtual void Move()
        { }
        [DataMember]
        protected bool state = true;
        [DataMember]
        protected float widthPen = 1;
        [DataMember]
 
        protected XmlColor clr;
 
        [DataMember]
        protected Point center;
        [DataMember]
        // [XmlAttribute("Center")]
        public XmlPoint Center
        {
            get
            {
                return center;
            }
            set { }
        }
        [XmlIgnore]
        [NonSerialized]
        protected Pen pen;
        public void InitializePen()
        {
            pen = new Pen(clr, widthPen);
        }
        public float WidthPen
        {
            get
            {
                return widthPen;
            }
            set
            {
                
                widthPen = value;
                InitializePen();
                pen.Width = widthPen;
            }
        }            
        public bool Running
        {
            get
            {
                return state;
            }
            set
            {
                state = value;
            }
        }
        public XmlColor ObjectColor
        {
            get
            {
                return clr;
            }
            set
            {
                clr = value;
            }
        }
        public string NameFigure()
        {
            return Name;
        }
        public string PositionX()
        {
            return null;
        }
        public string PositionY()
        {
            return null;
        }
    }
}


у него есть класс наследник Circle
Circle
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Rnd;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace DCT
{
    [Serializable]
    [XmlType]
    public class Circle : Figure
    {
        public Circle() {}
        public Circle(Size size, string Name)
        {
            this.Name = Name;
            maxSpeed = 5;
            minSpeed = -5;
            minDiameter = 10;
            maxDiameter = 35;
            indent = 35;
 
            Rnd.Haphazard hapz = new Rnd.Haphazard();
 
            clr = Color.FromArgb(hapz.redColor(),hapz.greenColor(),hapz.blueColor());
            pen = new Pen(clr, widthPen);
            canvaSize = size;
            dx = hapz.Speed(minSpeed, maxSpeed);
            dy = hapz.Speed(minSpeed, maxSpeed);
            recCircle = hapz.rect(canvaSize.Width - indent, canvaSize.Height - indent, minDiameter, maxDiameter);
            radius = recCircle.Width / 2;
            center.X = recCircle.X + radius;
            center.Y = recCircle.Y + radius;
        }
        [DataMember]
        [XmlAttribute("maxSpeed")]
        public int maxSpeed { set; get; }
        [DataMember]
        [XmlAttribute("minSpeed")]
        public int minSpeed { set; get; }
        [DataMember]
        [XmlAttribute("minDiameter")]
        public int minDiameter { set; get; }
        [DataMember]
        [XmlAttribute("maxDiameter")]
        public int maxDiameter { set; get; }
        [DataMember]
        [XmlAttribute("indent")]
        public int indent { set; get; }
        [DataMember]
        [XmlAttribute("radius")]
        public int radius { set; get; }
        [DataMember]
        public Size canvaSize { set; get; }
        [DataMember]
        [XmlAttribute("dx")]
        public int dx { set; get; }
        [DataMember]
        [XmlAttribute("dy")]
        public int dy { set; get; }
        [DataMember]
       
        public System.Drawing.Rectangle recCircle;
 
        public int GetRadius()
        {
            return radius;
        }
        public override void Draw(Graphics g)
        {
 
            g.DrawEllipse(pen, recCircle);
            g.DrawRectangle(pen, center.X, center.Y, 1, 1);
 
        }
        public override void Move()
        {
            if (state)
            {
                if (recCircle.X + recCircle.Width > canvaSize.Width)
                {
                    dx = -Math.Abs(dx);
                }
                if (recCircle.Y + recCircle.Height > canvaSize.Height)
                {
                    dy = -Math.Abs(dy);
                }
                if (recCircle.X < 0)
                {
                    dx = Math.Abs(dx);
                }
                if (recCircle.Y < 0)
                {
                    dy = Math.Abs(dy);
                }
                center.X += dx;
                center.Y += dy;
                recCircle.X += dx;
                recCircle.Y += dy;
            }
        } 
    }
}


Объект XmlColor - из статьи Сериализация несереализируемого:
Кликните здесь для просмотра всего текста
по аналогии думаю переопределить другие структуры

XmlColor
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 [Serializable]
    public struct XmlColor : System.Xml.Serialization.IXmlSerializable
    {
        private Color _color;
 
        public XmlColor(Color c)
        {
            _color = c;
        }
 
        public Color Color
        {
            get { return _color; }
        }
        public static implicit operator Color(XmlColor c)
        {
            return c.Color;
        }
 
        public static implicit operator XmlColor(Color c)
        {
            return new XmlColor(c);
        }
        System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }
 
        void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
        {
            _color = ColorTranslator.FromHtml(reader.ReadString());
        }
        void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteString(ColorTranslator.ToHtml(this.Color));
        }
    }


Я создаю список объектов

C#
1
2
List<Figure> lst;
lst.Add(new Circle(pictureBox1.Size, "Circle " + (++objCount).ToString()));
и так несколько различных объектов в рендомных местах.

при сериализации использую такой код:
C#
1
2
3
4
5
XmlSerializer writer = new XmlSerializer(typeof(List<Figure>));
                     FileStream sw = new FileStream(sfd.FileName, FileMode.Create, FileAccess.ReadWrite);
                     StreamWriter file = new StreamWriter(sw);
                     writer.Serialize(file, lst);
                     file.Close();
XML
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<ArrayOfFigure xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Figure xsi:type="Circle" maxSpeed="5" minSpeed="-5" minDiameter="10" maxDiameter="35" indent="35" radius="14" dx="1" dy="-1">
<Name>Circle 1</Name>
<Center>73,260</Center>
<WidthPen>1</WidthPen>
<Running>false</Running>
<ObjectColor>#AF03D3</ObjectColor>
<recCircle>
<Location>
<X>59</X>
<Y>246</Y>
</Location>
<Size>
<Width>29</Width>
<Height>29</Height>
</Size>
<X>59</X>
<Y>246</Y>
<Width>29</Width>
<Height>29</Height>
</recCircle>
<canvaSize>
<Width>656</Width>
<Height>348</Height>
</canvaSize>
</Figure>
<Figure xsi:type="Circle" maxSpeed="5" minSpeed="-5" minDiameter="10" maxDiameter="35" indent="35" radius="17" dx="2" dy="4">
<Name>Circle 2</Name>
<Center>94,300</Center>
<WidthPen>1</WidthPen>
<Running>false</Running>
<ObjectColor>#586262</ObjectColor>
<recCircle>
<Location>
<X>77</X>
<Y>283</Y>
</Location>
<Size>
<Width>34</Width>
<Height>34</Height>
</Size>
<X>77</X>
<Y>283</Y>
<Width>34</Width>
<Height>34</Height>
</recCircle>
<canvaSize>
<Width>656</Width>
<Height>348</Height>
</canvaSize>
</Figure>
</ArrayOfFigure>


ну вроде бы всё не плохо.

а вот Десериализация...
вот код

C#
1
2
3
4
                    XmlSerializer serializer = new XmlSerializer(typeof(List<Figure>));
                    TextReader textReader = new StreamReader(ofd.FileName);
                    lst = (List<Figure>)serializer.Deserialize(textReader);
                    textReader.Close();
и возвращается в мой список всего 1 элемент.

и я не могу понять в чем дело.

подскажите в десериализации.

p.s. уже реализована сериализация в *.bin и в формат *.json
это обучающее приложение и это моя первая сериализация. вполне вероятного какой-то атрибут не дал. по-этому прошу подсказать или дать толковую стать по моей теме.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.07.2013, 20:44
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Сериализация/Десериализация списка объектов в XML (C#):

XML сериализация списка
По какой схеме нужно сериализовать однонаправленный упорядоченный список?...

Сериализация / десериализация
доброе время суток=) такое задание - отправить объект класса с приложения...

Сериализация и десериализация
Доброго вечера. Возникло странное непонимание принципов сериализации. Дело в...

Protobuf сериализация десериализация
Добрый день уважаемые форумчане. Помогите разобраться. Имеется клиент...

Помогите плз по C#, сериализация десериализация
В одной программе сохраняю объект: saveFileDialog.Title = &quot;Сохранение теста&quot;;...

Десериализация объектов в массив.
Приведу сначала код того, что я сериализирую, как сериализирую и как пытаюсь...

6
Psilon
Master of Orion
Эксперт .NET
5981 / 4834 / 901
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 5
Завершенные тесты: 4
10.07.2013, 00:21 #2
Не знаю, вот рабочий код, сравните, может чего углядите (просто поздновато, извиняюсь за лень )
C#
1
2
3
4
5
6
7
8
9
10
11
using System.Xml.Serialization;
 
namespace WpfLogin
{
    [XmlType]
    public class Person
    {
        public string Login { get; set; }
        public string Password { get; set; }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
 
namespace WpfLogin
{
    public class Repository : IRepository
    {
        private const string Filename = "rep.xml";
 
        static readonly XmlSerializer Serializer = new XmlSerializer(typeof(Person[]));
 
        public IEnumerable<Person> Persons
        {
            get
            {
                try
                {
                    using (var fileStream = new FileStream(Filename, FileMode.Open))
                    {
                        return (IEnumerable<Person>) Serializer.Deserialize(fileStream);
                    }
                }
                catch
                {
                    return Enumerable.Empty<Person>();
                }
            }
        }
 
        public void Add(Person person)
        {
            var persons = Persons.ToList();
            persons.Add(person);
            using (var fileStream = new FileStream(Filename, FileMode.Create))
            {
                Serializer.Serialize(fileStream, persons.ToArray());
            }
        }
    }
}
1
krupa
106 / 106 / 35
Регистрация: 13.12.2010
Сообщений: 407
10.07.2013, 02:09  [ТС] #3
сделал вот так вот

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
foreach (Figure f in lst)
      Add(f);
///
public void Add(Figure f)
        {
            var fs = Figures.ToList();
            fs.Add(f);
            using (var fileStream = new FileStream(FileName, FileMode.Create))
            {
                Serializer.Serialize(fileStream, fs);
            }
        }
 
////
вот ХМЛ сериализированных 2 объектов
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<ArrayOfFigure xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Figure xsi:type="Circle" maxSpeed="5" minSpeed="-5" minDiameter="10" maxDiameter="35" indent="35" radius="15" dx="4" dy="-3">
<Name>Circle 1</Name>
<Center>0,0</Center>
<WidthPen>1</WidthPen>
<Running>true</Running>
<ObjectColor/>
<recCircle>
<Location>
<X>0</X>
<Y>0</Y>
</Location>
<Size>
<Width>0</Width>
<Height>0</Height>
</Size>
<X>0</X>
<Y>0</Y>
<Width>0</Width>
<Height>0</Height>
</recCircle>
<canvaSize>
<Width>0</Width>
<Height>0</Height>
</canvaSize>
</Figure>
<Figure xsi:type="Circle" maxSpeed="5" minSpeed="-5" minDiameter="10" maxDiameter="35" indent="35" radius="5" dx="-1" dy="4">
<Name>Circle 2</Name>
<Center>578,39</Center>
<WidthPen>1</WidthPen>
<Running>true</Running>
<ObjectColor>#07BE8C</ObjectColor>
<recCircle>
<Location>
<X>573</X>
<Y>34</Y>
</Location>
<Size>
<Width>10</Width>
<Height>10</Height>
</Size>
<X>573</X>
<Y>34</Y>
<Width>10</Width>
<Height>10</Height>
</recCircle>
<canvaSize>
<Width>656</Width>
<Height>348</Height>
</canvaSize>
</Figure>
</ArrayOfFigure>


вот десерилизация

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static readonly XmlSerializer Serializer = new XmlSerializer(typeof(List<Figure>));
        public IEnumerable<Figure> Figures
        {
            get
            {
                try
                {
                    using (var fileStream = new FileStream(FileName, FileMode.Open))
                    {
                        return (IEnumerable<Figure>)Serializer.Deserialize(fileStream);
                    }
                }
                catch
                {
                    return Enumerable.Empty<Figure>();
                }
            }
        }
 
IEnumerable<Figure> fff = Figures;
                    lst.Clear();
                    lst = fff.ToList();
и всё равно, после десиарилизации в lst - всего один объект (первый)


ещё, может это важно
начинается хмл-документ с такого текста:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
0
Psilon
Master of Orion
Эксперт .NET
5981 / 4834 / 901
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 5
Завершенные тесты: 4
10.07.2013, 05:23 #4
krupa, лично я сериализовывал массив. У списка есть всякие левые параметры, поэтому я не стал рисковать. Хотя может разницы и нет. НО например при бинарной сериализации есть. Например список из двух элементов 1 2, сериализуется как массив из четырех элементов 1 2 0 0 со свойством Count = 2;
1
krupa
106 / 106 / 35
Регистрация: 13.12.2010
Сообщений: 407
10.07.2013, 13:21  [ТС] #5
делал - результат тот же

я не могу понять, почему в хмл два объекта, в десериализирует только один. первый.
0
Psilon
Master of Orion
Эксперт .NET
5981 / 4834 / 901
Регистрация: 10.07.2011
Сообщений: 14,439
Записей в блоге: 5
Завершенные тесты: 4
10.07.2013, 13:51 #6
Мне кажется это из-за того, что вы наследуете от IXmlSerializable
1
krupa
106 / 106 / 35
Регистрация: 13.12.2010
Сообщений: 407
10.07.2013, 14:06  [ТС] #7
XmlSerializer не может выполнить десериализацию следующего: массивы ArrayList и массивы List<T>.
вот такую цитату на msdn выловил
(

Добавлено через 4 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
Мне кажется это из-за того, что вы наследуете от IXmlSerializable
Большое спасибо
сделал без этого интерфейса и всё стало нормально
1
10.07.2013, 14:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.07.2013, 14:06
Привет! Вот еще темы с решениями:

Десериализация XML
Пытаюсь десереализировать XML структуру, но или получаю неверное соответствие...

Десериализация XML
Коллеги, помогите десериализовать данные &lt;?xml version=&quot;1.0&quot;...

XML десериализация
Здравствуйте, помогите пожалуйста разобраться. &lt;?xml version=&quot;1.0&quot;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru