Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
 
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
#1

Добавление данных в XML не верно - C#/.NET 4.x

07.03.2017, 09:04. Просмотров 274. Ответов 17
Метки нет (Все метки)

Доброго всем времени суток,
Вот моя проблема, написана программа по примеру, она добавляет/редактирует/удаляет строки в XML в общем она работает, но создает данные не в том формате, что мне надо т.е
Мне нужно так
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
<comp_it_xml>
<entry 
icon="matt"
title="Тестовый товар 1" 
description="Мини описание" 
fulldescription="Полное описание"
price="150"/>
....
</comp_it_xml>

Но создает так
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
<comp_it_xml>
  <entry>
    <icon>matt.png</icon>
    <title>Test 3</title>
    <description>dfgdg dfz gfdz dg</description>
    <fulldescription> fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f </fulldescription>
    <price>130</price>
  </entry>
....
</comp_it_xml>


вот код
Кликните здесь для просмотра всего текста
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
public partial class Form1 : Form
    {
        public static string conf;
        public Form1()
        {
            InitializeComponent();
 
            CIASystem.config();
            CIASystem conf = new Core.CIASystem();
 
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            
            
            // label
            lb_icon.Text = "Иконка";
            lb_title.Text = "Название";
            lb_description.Text = "Описание";
            lb_fulldescription.Text = "Полное описание";
            lb_price.Text = "Цена";
 
            // button
            btn_addProduct.Text = "Добавить продукт";
            btn_editProduct.Text = "Редактировать продукт";
            btn_delProduct.Text = "Удалить продукт";
            btn_saveAsXml.Text = "Сохранить как XML";
            btn_clearTable.Text = "Очистить столбцы";
            btn_downXml.Text = "Загрузить XML";
        }
 
        private void btn_addProduct_Click(object sender, EventArgs e)
        {
            if (tb_icon.Text == "")
            {
                MessageBox.Show("Заполните все поля.", "Ошибка.");
            }
            else
            {
                int n = dg_listProduct.Rows.Add();
                dg_listProduct.Rows[n].Cells[0].Value = tb_icon.Text;
                dg_listProduct.Rows[n].Cells[1].Value = tb_title.Text;
                dg_listProduct.Rows[n].Cells[2].Value = tb_description.Text;
                dg_listProduct.Rows[n].Cells[3].Value = tb_fulldescription.Text;
                dg_listProduct.Rows[n].Cells[4].Value = tb_price.Text;
            }
        }
 
        private void btn_editProduct_Click(object sender, EventArgs e)
        {
            if (dg_listProduct.SelectedRows.Count > 0)
            {
                int n = dg_listProduct.SelectedRows[0].Index;
                dg_listProduct.Rows[n].Cells[0].Value = tb_icon.Text;
                dg_listProduct.Rows[n].Cells[1].Value = tb_title.Text;
                dg_listProduct.Rows[n].Cells[2].Value = tb_description.Text;
                dg_listProduct.Rows[n].Cells[3].Value = tb_fulldescription.Text;
                dg_listProduct.Rows[n].Cells[4].Value = tb_price.Text;
            }
            else
            {
                MessageBox.Show("Выберите строку для редактирования.", "Ошибка.");
            }
        }
 
        private void btn_delProduct_Click(object sender, EventArgs e)
        {
            if (dg_listProduct.SelectedRows.Count > 0)
            {
                dg_listProduct.Rows.RemoveAt(dg_listProduct.SelectedRows[0].Index);
            }
            else
            {
                MessageBox.Show("Выберите строку для удаления.", "Ошибка.");
            }
        }
 
        private void btn_clearTable_Click(object sender, EventArgs e)
        {
            if (dg_listProduct.Rows.Count > 0)
            {
                dg_listProduct.Rows.Clear();
            }
            else
            {
                MessageBox.Show("Таблица пустая.", "Ошибка.");
            }
        }
 
        private void btn_downXml_Click(object sender, EventArgs e)
        {
            if (dg_listProduct.Rows.Count > 0) //если в таблице больше нуля строк
            {
                MessageBox.Show("Очистите поле перед загрузкой нового файла.", "Ошибка.");
            }
            else
            {
                if (File.Exists("comp_it_xml.xml")) // если существует данный файл
                {
                    DataSet ds = new DataSet(); // создаем новый пустой кэш данных
                    ds.ReadXml("comp_it_xml.xml"); // записываем в него XML-данные из файла
 
                    foreach (DataRow item in ds.Tables["entry"].Rows)
                    {
                        int n = dg_listProduct.Rows.Add(); // добавляем новую сроку в dataGridView1
                        dg_listProduct.Rows[n].Cells[0].Value = item["icon"]; // заносим в первый столбец созданной строки данные из первого столбца таблицы ds.
                        dg_listProduct.Rows[n].Cells[1].Value = item["title"]; // то же самое со вторым столбцом
                        dg_listProduct.Rows[n].Cells[2].Value = item["description"]; // то же самое с третьим столбцом
                        dg_listProduct.Rows[n].Cells[3].Value = item["fulldescription"]; // то же самое с третьим столбцом
                        dg_listProduct.Rows[n].Cells[4].Value = item["price"]; // то же самое с третьим столбцом
                    }
                }
                else
                {
                    MessageBox.Show("XML файл не найден.", "Ошибка.");
                }
            }
        }
 
        private void btn_saveAsXml_Click(object sender, EventArgs e)
        {
            try
            {
                DataSet ds = new DataSet("comp_it_xml"); // создаем пока что пустой кэш данных
                DataTable dt = new DataTable(); // создаем пока что пустую таблицу данных
                dt.TableName = "entry"; // название таблицы
                dt.Columns.Add("icon"); // название колонок
                dt.Columns.Add("title");
                dt.Columns.Add("description");
                dt.Columns.Add("fulldescription");
                dt.Columns.Add("price");
                ds.Tables.Add(dt); //в ds создается таблица, с названием и колонками, созданными выше
 
                foreach (DataGridViewRow r in dg_listProduct.Rows) // пока в dataGridView1 есть строки
                {
                    DataRow row = ds.Tables["entry"].NewRow(); // создаем новую строку в таблице, занесенной в ds
                    row["icon"] = r.Cells[0].Value;  //в столбец этой строки заносим данные из первого столбца dataGridView1
                    row["title"] = r.Cells[1].Value; // то же самое со вторыми столбцами
                    row["description"] = r.Cells[2].Value; //то же самое с третьими столбцами
                    row["fulldescription"] = r.Cells[3].Value; //то же самое с третьими столбцами
                    row["price"] = r.Cells[4].Value; //то же самое с третьими столбцами
                    ds.Tables["entry"].Rows.Add(row); //добавление всей этой строки в таблицу ds.
                }
                ds.WriteXml("comp_it_xml.xml");
                MessageBox.Show("XML файл успешно сохранен.", "Выполнено.");
            }
            catch
            {
                MessageBox.Show("Невозможно сохранить XML файл.", "Ошибка.");
            }
        }
 
        private void dg_listProduct_MouseClick(object sender, MouseEventArgs e)
        {
            try
            { 
            tb_icon.Text = dg_listProduct.SelectedRows[0].Cells[0].Value.ToString();
            //int n = Convert.ToInt32(dg_listProduct.SelectedRows[0].Cells[1].Value);
            //numericUpDown1.Value = n;
            tb_title.Text = dg_listProduct.SelectedRows[0].Cells[1].Value.ToString();
            tb_description.Text = dg_listProduct.SelectedRows[0].Cells[2].Value.ToString();
            tb_fulldescription.Text = dg_listProduct.SelectedRows[0].Cells[3].Value.ToString();
            tb_price.Text = dg_listProduct.SelectedRows[0].Cells[4].Value.ToString();
            }
            catch
            {
                //MessageBox.Show("Невозможно сохранить XML файл.", "Ошибка.");
                toolStripStatusLabel1.Text = "Ошибка. - Невозможно открыть XML файл.";
            }
        }
 
        private void btn_uploadToFtp_Click(object sender, EventArgs e)
        {
 
        }
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.03.2017, 09:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос .NET 4.x Добавление данных в XML не верно (C#):

Добавление данных в XML - C#
Проблема следующая . Есть XML файл &lt;?xml version=&quot;1.0&quot;?&gt; &lt;Accounts&gt; &lt;Resource res=&quot;Res&quot;&gt; &lt;Login log=&quot;Log&quot;&gt; ...

Добавление данных в XML - C#
Здравствуйте. Есть такой XML-документ: &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; - &lt;UICustomizationSet...

Добавление данных в XML файл с несколькими родительскими элементами - C#
Есть xml файл &lt;?xml version=&quot;1.0&quot; encoding=&quot;windows-1251&quot; standalone=&quot;yes&quot;?&gt; &lt;NewDataSet&gt; &lt;private&gt; &lt;id&gt;1&lt;/id&gt; ...

Добавление, изменение данных в XML файле - C#
Здравствуйте! Не могу понять как: 1. можно добавлять данные в xml без перетирания существующих в нем данных 2. можно редактировать...

Добавление данных в существующий xml файл - C#
Всем привет! Как открыть и прочитать xml разобрался. не получается добавить данные в определенное место т.е. структура такая ...

XmlSerializer, добавление данных в XML и ошибка "файл занят" - C#
Помогите плз, нужно сделать добавление инф. в XML, что бы предыдущая не затиралась, я написал код, но когда идет запись вылезает ошибка,...

17
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 10:02 #2
CoMMoN86, со 128 по 132 строки ты добавляешь столбцы в таблицу. Надо немного изменить эту часть кода. При добавлении столбца надо его немного инициализировать. У столбца есть свойство ColumnMapping, ему надо присвоить значение Attribute, поскольку по умолчанию оно имеет значение Element. Как-то так
C#
1
2
3
4
            DataTable dt = new DataTable(); // создаем пока что пустую таблицу данных
            dt.TableName = "entry";
            var col = dt.Columns.Add("icon");
            col.ColumnMapping = MappingType.Attribute;
1
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
07.03.2017, 11:03  [ТС] #3
diadiavova, вроде все работает, только вот все в одну строку
XML
1
2
3
4
5
6
<?xml version="1.0" standalone="yes"?>
<comp_it_xml>
  <entry icon="matt.png" title="Test 3" description="dfgdg dfz gfdz dg" fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f " price="130" />
  <entry icon="matt.png" title="Test 3" description="dfgdg dfz gfdz dg" fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f " price="130" />
  <entry icon="matt.png" title="Test 3" description="ggjyjg fhh" fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f " price="132" />
</comp_it_xml>
как сделать чтобы спускались?
И как убрать это
XML
1
<?xml version="1.0" standalone="yes"?>
в начале, он мне не нужен
0
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 11:22 #4
CoMMoN86, ты знаешь, все можно сделать вообще как тебе заблагорассудится, только для того, чтобы этого добиться тебе придется отказаться от встроенных инструментов и выполнять сохранение вручную. Либо можно сохранять как есть, а потом еще выполнять дополнительную обработку файла.
0
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
07.03.2017, 11:30  [ТС] #5
diadiavova,
Цитата Сообщение от diadiavova Посмотреть сообщение
Либо можно сохранять как есть, а потом еще выполнять дополнительную обработку файла.
Давай наверное лучше это т.к вручную не подходит
0
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 12:37 #6
Цитата Сообщение от CoMMoN86 Посмотреть сообщение
Давай наверное лучше это т.к вручную не подходит
Нет, ну в каком-то объеме этим процессом управлять, конечно, можно. Тут все зависит от того, что значит выражение "чтобы спускались". Если речь идет о том, чтобы было как в твоем примере, то есть каждый элемент на отдельной строке, то этого можно добиться и встроенными средствами, а вот если тебе надо скажем, чтобы еще каждый атрибут на отдельной строке отображался, то тут придется химичить и немало. В общем и целом: основные возможности настройки сохранения кроются в перегрузках метода WriteXml. Можно выбрать запись с помощью XmlWriter и задать ему настройки.
C#
1
2
3
4
5
6
7
8
9
10
11
12
            var writerSettings = new XmlWriterSettings()
            {
                OmitXmlDeclaration = true,
                Indent = true,
                Encoding = Encoding.UTF8
            };
            
            using (XmlWriter writer = XmlTextWriter.Create(filename, writerSettings))
            {
                
                dt.WriteXml(writer);
            }
Но вообще, чтобы произвольное форматирование реализовать, то помучиться придется немало. Можно, конечно, попытаться написать наследника XmlTextWriter, но там тоже не все так просто.
0
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
07.03.2017, 14:33  [ТС] #7
diadiavova, мне нужно чтобы было как у меня в примере
0
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 14:37 #8
Цитата Сообщение от CoMMoN86 Посмотреть сообщение
мне нужно чтобы было как у меня в примере
Ну последний мой пример что-то в этом роде по идее и должен делать. Просто когда ты написал этот пример, я подумал, что это то, что получается, то есть каждый элемент целиком в одну строку, а тебе надо атрибуты по строкам разбить. Но так как в твоем примере можно и XML-декларацию тоже убрать можно. Это достигается настройкой параметров райтера, как это показано выше.
0
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
07.03.2017, 14:42  [ТС] #9
diadiavova, ну, а можно пример, а то уже ее заканчивать пора
0
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 14:45 #10
Цитата Сообщение от CoMMoN86 Посмотреть сообщение
ну, а можно пример
А то что я выше привел - это что? Ты сохраняешь таблицу, просто вызывая WriteXml и передавая этому методу имя файла. Вместо этого надо сохранять, вызывая перегрузку этого метода, принимающую XmlWriter. При этом надо сначала создать объект с параметрами сохранения, передать их при создании райтера и использовать его. Код я привел выше.
0
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
07.03.2017, 14:52  [ТС] #11
diadiavova, убрала
XML
1
2
3
    
 
<?xml version="1.0" standalone="yes"?>
но все равно в строчку
XML
1
2
3
4
5
<comp_it_xml>
  <entry icon="matt.png" title="Test 3" description="dfgdg dfz gfdz dg" fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f " price="130" />
  <entry icon="matt.png" title="Test 3" description="dfgdg dfz gfdz dg" fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f " price="130" />
  <entry icon="matt.png" title="Test 3" description="ggjyjg fhh" fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f " price="132" />
</comp_it_xml>
а надо вот
XML
1
2
3
4
5
6
7
8
9
<comp_it_xml>
<entry 
icon="matt"
title="Тестовый товар 1" 
description="Мини описание" 
fulldescription="Полное описание"
price="150"/>
....
</comp_it_xml>
0
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 15:39 #12
Цитата Сообщение от CoMMoN86 Посмотреть сообщение
а надо вот
Ну так я же об этом писал уже: это произвольный формат, который встроенными возможностями не предусмотрен, так что тут придется собственный райтер реализовывать, а это непросто. Я попробовал вставлять перевод строк в наследнике XmlTextWriter, но они почему-то все вставляются в начало документа. А создать свой райтер из XmlWriter - это долго и муторно, там довольно много абстрактных методов и все нужно реализовать. Можно, конечно, и с другими вариантами поколдовать, но в любом случае - простым решение не будет.
Цитата Сообщение от diadiavova Посмотреть сообщение
Просто когда ты написал этот пример, я подумал, что это то, что получается, то есть каждый элемент целиком в одну строку, а тебе надо атрибуты по строкам разбить.
Таки сначала я правильно подумал))
0
CoMMoN86
-8 / 2 / 1
Регистрация: 18.05.2013
Сообщений: 479
07.03.2017, 15:44  [ТС] #13
diadiavova, ясно, тогда может можно это переделать под нужное
Android java
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 XmlPullParser parser = getResources().getXml(R.xml.comp_it_xml);
 
            while (parser.getEventType()!= XmlPullParser.END_DOCUMENT) {
                if (parser.getEventType() == XmlPullParser.START_TAG
                        && parser.getName().equals("entry")) {
 
 
                    hm = new HashMap<>();
                    hm.put(ICON, R.drawable.korpus); // Картинка
                    hm.put(TITLE, parser.getAttributeValue(1)); // Название
                    hm.put(DESCRIPTION, parser.getAttributeValue(2)); // Описание
                    hm.put(FULLDESCRIPTION, parser.getAttributeValue(3)); // Полное описание
                    hm.put(PRICE, parser.getAttributeValue(4)); // Полное описание
 
                    mCatList.add(hm);
 
 
                }
в место цифр слова icon,title и т.п
0
diadiavova
1851 / 987 / 274
Регистрация: 11.04.2015
Сообщений: 1,832
Записей в блоге: 31
07.03.2017, 16:04 #14
Цитата Сообщение от CoMMoN86 Посмотреть сообщение
тогда может можно это переделать под нужное
Android java
Дык для явы или чего бы то ни было еще, форматирование атрибутов вообще не имеет значения. Это может иметь значение для того, чтобы сделать документ более читабельным для человека, поскольку длинные строки читать неудобно, а для машины это значения не имеет.

Что касается кода, ну там же есть еще метод getAttributeName. Ну получить пару имя-значение таким образом несложно ведь. А если перейдешь на инструменты Xamarin, то там, насколько я помню, есть пространство System.Xml со знакомыми по фреймворку API.
0
TopLayer
716 / 539 / 206
Регистрация: 23.10.2016
Сообщений: 1,273
Завершенные тесты: 7
07.03.2017, 17:10 #15
Такое костылище
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<comp_it_xml
><entry
 icon="matt.png"
 title="Test 3"
 description="dfgdg dfz gfdz dg"
 fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f "
 price="130"
 />
<entry
 icon="matt.png"
 title="Test 3"
 description="dfgdg dfz gfdz dg"
 fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f "
 price="130"
 />
<entry
 icon="matt.png"
 title="Test 3"
 description="ggjyjg fhh"
 fulldescription=" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f "
 price="132"
 />
</comp_it_xml
Кликните здесь для просмотра всего текста
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
void Main()
{
    var set = new DataSet();
    set.ReadXml(new XmlTextReader(new StringReader(db)));
    
    set.WriteXml(new MyXml(Console.Out));
}
 
string db = @"<?xml version=""1.0"" standalone=""yes""?>
<comp_it_xml>
  <entry icon=""matt.png"" title=""Test 3"" description=""dfgdg dfz gfdz dg"" fulldescription="" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f "" price=""130"" />
  <entry icon=""matt.png"" title=""Test 3"" description=""dfgdg dfz gfdz dg"" fulldescription="" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f "" price=""130"" />
  <entry icon=""matt.png"" title=""Test 3"" description=""ggjyjg fhh"" fulldescription="" fdgr dfgghghgfhdg h dfg fgs fgs fgs fgs f "" price=""132"" />
</comp_it_xml>
";
 
class MyXml : XmlTextWriter
{
    TextWriter writer;
    
    public MyXml(TextWriter writer):
        base(writer)
    {
        this.writer = writer;
    }
    
    public override void WriteStartAttribute(string prefix, string localName, string ns)
    {
        writer.Write("\n");
        base.WriteStartAttribute(prefix, localName, ns);
    }
    
    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        writer.Write("\n");
        base.WriteStartElement(prefix, localName, ns);
    }
    
    public override void WriteEndElement()
    {
        writer.Write("\n");
        base.WriteEndElement();
    }
}
1
07.03.2017, 17:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.03.2017, 17:10
Привет! Вот еще темы с ответами:

XML добавление и редактирование - C#
Доброго времени. У меня возникла проблема. Сегодня впервые решил познакомиться с XML и начать с ним работать. По учебнику и интернету я...

Добавление, а не перезапись XML - C#
Суть: System.IO.StreamWriter Перезаписывает данные(файл) Надо что бы данные добавляло к существующим вроде как в стриме...

XML. Добавление в файл - C#
Есть XML-файл со структурой типа &lt;root&gt; &lt;element1&gt; &lt;/element1&gt; &lt;element1&gt; &lt;/element1&gt; .... ...

Добавление и удаление узла в XML - C#
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;PassSaver&gt; &lt;profile name=&quot;1&quot; pass=&quot;2&quot;&gt; &lt;Service name=&quot;123&quot;&gt;&lt;/Service&gt; &lt;Service...


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

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

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