Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
.NET 4.x

Linq to XML

19.10.2018, 13:59. Показов 2236. Ответов 32
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Возник следующий вопрос. Делаю запрос к Web-сервису и в ответ получаю XML вида:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[COLOR="Red"]<sender>TestSender</msg_sender>
       <receiver>TestRec</msg_receiver>[/COLOR]
       <type>IN_REC</msg_type>
       <msg_info>
             <response_info>
                    <Header>
                           [COLOR="red"]<MsgId>ARM655655</MsgId>
                           <MsgTime>2018-10-16T17:44:17</MsgTime>
[/COLOR]                           <Status>P</Status>
                    </Header>
                    <Body>
                           [COLOR="red"]<UserName>Test</UserName>
                           <ClaimID>CL6555</ClaimID>
[/COLOR]                                <StsRsn>
                                       <Prtry>DD10</Prtry>
                                </StsRsn>
                    </Body>
             </response_info>
       </msg_info>"
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.10.2018, 13:59
Ответы с готовыми решениями:

Подсчитать количтво нодов в XML при помощи LINQ to XML
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;Root&gt; &lt;host&gt; 192.168.1.1 &lt;/host&gt; &lt;host&gt; 192.168.1.3 &lt;/host&gt; &lt;/Root&gt; как...

Объединение 2 xml файлов по ключу в 1 xml с использованием linq
День добрый. Я уже отписывался в другой теме с объединением 2 xml, но увы тот метод для меня слишком сложен. Видел на форумах ребята...

Создание xml документа посредством LINQ to XML
Добрый день. Мне необходимо создать xml-документ который будет включать следующие элементы: &lt;Envelope...

32
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
19.10.2018, 19:14
Цитата Сообщение от Estenity Посмотреть сообщение
Возник следующий вопрос. Делаю запрос к Web-сервису и в ответ получаю XML вида:
А вопрос в чём?
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
19.10.2018, 19:33
Элд Хасп, вопрос, почему файл невалидный ))
1
 Аватар для AlexP11223
141 / 110 / 30
Регистрация: 20.04.2011
Сообщений: 582
19.10.2018, 19:35
А мы откуда знаем почему сервер так отдает?
И что именно не валидно?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
19.10.2018, 21:18
Цитата Сообщение от amr-now Посмотреть сообщение
Элд Хасп, вопрос, почему файл невалидный ))
Я думаю Вы не правы, мне кажется вопрос: "Почему в седьмой строке между двумя 55 стоит шестёрка?".
0
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
20.10.2018, 18:36  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А вопрос в чём?
Цитата Сообщение от AlexP11223 Посмотреть сообщение
А мы откуда знаем почему сервер так отдает?
И что именно не валидно?
Цитата Сообщение от amr-now Посмотреть сообщение
Элд Хасп, вопрос, почему файл невалидный ))
Спасибо за внимание
Я просто не дописал вопрос, а вышло уже 5 минут на редактирование, не знал, извиняйте
Вопрос задам еще раз. Возвращается XML файл вида:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<root>
       <sender>TestSender</sender>
       <receiver>TestRec</receiver>
       <type>IN_REC</type>
       <msg_info>
             <response_info>
                    <Header>
                           <MsgId>ARM655655</MsgId>
                           <MsgTime>2018-10-16T17:44:17</MsgTime>
                           <Status>P</Status>
                    </Header>
                    <Body>
                          <UserName>Test</UserName>
                          <ClaimID>CL6555</ClaimID>
                          <StsRsn>
                                  <Prtry>DD10</Prtry>
                         </StsRsn>
                    </Body>
             </response_info>
       </msg_info>
</root>
Как мне грамотно вытащить с использованием Linq to XML (при этом не всегда нужна вся информация, а только некоторые узлы) ? И какую модель данных использовать в этом случае ?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
20.10.2018, 18:40
Цитата Сообщение от Estenity Посмотреть сообщение
Как мне грамотно вытащить с использованием Linq to XML ? И какую модель данных использовать в этом случае ?
Всё равно не понятно. Самые обычные Element, Elements, Atribute, Atributes, Name и т.д. и т.п. Что Вам собственно надо? В чём трудность?
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
20.10.2018, 19:34
Estenity, там народ пишет, что надо брать самую свежую загогулину. Старую загогулину нельзя брать. Говорят, фуфло.
Значит, сейчас будем искать ))

Добавлено через 29 минут
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
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
 
namespace Question2336802
{
    class Program
    {
        static void Main(string[] args)
        {
            string file_path = "C:/temp/test.txt";
            string str = File.ReadAllText(file_path, Encoding.UTF8);
            var doc = XDocument.Parse(str);
            Console.WriteLine(doc.Root.Element("msg_info").Element("response_info").Element("Body").Element("ClaimID").Value);
            Console.WriteLine();
            foreach (var item in doc.Root.Element("msg_info").Element("response_info").Element("Header").Elements()
                .Select(e => $"{e.Name}: " + (e.Name == "MsgTime" ? DateTime.Parse(e.Value).ToShortDateString() : e.Value)))
            {
                Console.WriteLine($"{item}");
            }
 
            Console.ReadKey();
        }
    }
}
Дату переформатировал...
1
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
22.10.2018, 11:39  [ТС]
amr-now, спасибо! Помогло более менее разобраться.
А как быть в таких случаях:

XML
1
2
3
4
5
6
7
8
<Body>
    <UserName>Test</UserName>
    <ClaimID>CL6555</ClaimID>
    <StsRsn>
        <Prtry>DD10</Prtry>
        <AddStInf>Принят</AddStInf>
    </StsRsn>
</Body>
Если сделать проход по Body, то для тегов Prtry и AddStInf будет конкатенация их значений. Как это обойти?
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
22.10.2018, 11:54
Estenity, если нужно вытащить значения тех двух самых вложенных элементов:
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
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
 
namespace Question2336802
{
    class Program
    {
        static void Main(string[] args)
        {
            string file_path = "C:/temp/test2336802.txt";
            string str = File.ReadAllText(file_path, Encoding.UTF8);
            var doc = XDocument.Parse(str);
 
            foreach (var item in doc.Element("Body").Element("StsRsn").Elements())
            {
                Console.WriteLine($"{item.Value}");
            }
 
            Console.ReadKey();
        }
    }
}
0
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
22.10.2018, 12:19  [ТС]
amr_now, не совсем так. Я имел ввиду можно ли пройтись по всему Body в одном цикле. Т.е в случае:

C#
1
2
3
4
 foreach (var item in doc.Element("Body").Elements())
            {
                Console.WriteLine($"{item.Value}");
            }
Оно вернет конкатенацию значений всех вложенных элементов. Т.е для тега <StsRsn> вернется значение "DD10Принят" для данного примера.
Хотелось бы разложить все по своим элементам.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
22.10.2018, 12:41
Цитата Сообщение от Estenity Посмотреть сообщение
Я имел ввиду можно ли пройтись по всему Body в одном цикле. Т.е в случае:
В одном цикле нельзя - это же дерево а не линейный список. Для каждого узла для прохода по дочерним узлам нужен свой цикл.
Можно использую LINQ всё вытащить на один уровень, но тогда будет полная каша, непонятно где родительские элементы, где дочерние.
Цитата Сообщение от Estenity Посмотреть сообщение
Оно вернет конкатенацию значений всех вложенных элементов. Т.е для тега <StsRsn> вернется значение "DD10Принят" для данного примера.
Хотелось бы разложить все по своим элементам.
Не Вы не правы. Для тега <StsRsn> вернёт пустое значение так как Value у него не определенно, а цикла по дочерним узлам нет.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
22.10.2018, 12:45
Примитивное недодерево без рекурсии:
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
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
 
namespace Question2336802
{
    class Program
    {
        static void Main(string[] args)
        {
            string file_path = "C:/temp/test2336802.txt";
            string str = File.ReadAllText(file_path, Encoding.UTF8);
            var doc = XDocument.Parse(str);
 
            foreach (var item in doc.Element("Body").Elements())
            {
                if (item.Elements().Count() == 0)
                    Console.WriteLine($"{item.Value}");
                else
                    foreach (var item2 in item.Elements())
                    {
                        Console.WriteLine($"    {item2.Value}");
                    }
            }
 
            Console.ReadKey();
        }
    }
}
Estenity, цель же обычно не просто вывести дерево, а поместить в типизированную структуру данных или в крайнем случае преобразовать.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
22.10.2018, 12:49
Что бы получить значения дочерних нужен ещё один вложенный цикл
C#
1
2
3
4
5
6
7
8
9
 
            foreach (var item in doc.Element("Body").Elements())
            {
                Console.WriteLine($"{item.Value}");
                foreach (var child in item.Elements())
                {
                       Console.WriteLine($"{child.Value}");
                 }
            }
Добавлено через 3 минуты
Цитата Сообщение от Estenity Посмотреть сообщение
Как мне грамотно вытащить с использованием Linq to XML (при этом не всегда нужна вся информация, а только некоторые узлы) ? И какую модель данных использовать в этом случае ?
Цитата Сообщение от amr-now Посмотреть сообщение
Estenity, цель же обычно не просто вывести дерево, а поместить в типизированную структуру данных или в крайнем случае преобразовать.
Estenity, Вы действительно определитесь более точно что Вам нужно. Просто вывести на консоль определённые элементы, узлы XML?
Создать по XML свой класс, структуру? Если да, то какие? Их свойства, поля и т.д.
0
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
22.10.2018, 13:55  [ТС]
amr-now, cпасибо! Это уже, то, что хотел.
Цитата Сообщение от amr-now Посмотреть сообщение
Estenity, цель же обычно не просто вывести дерево, а поместить в типизированную структуру данных или в крайнем случае преобразовать.
Да, планирую засунуть весь результат в модель вида:
C#
1
2
3
4
5
6
7
8
9
10
11
  public class Claim
        {
            public string Sender { get; set; }
            public string Receiver { get; set; }
            public string MsgID { get; set; }
            public DateTime MsgTime { get; set; }
            public char Status { get; set; }
            public string ClaimID { get; set; }
            public string Prtry { get; set; }
            public string AddStInf { get; set; }
        }
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Не Вы не правы. Для тега <StsRsn> вернёт пустое значение так как Value у него не определенно, а цикла по дочерним узлам нет
Не в этом суть, но тогда прошу объяснить, что делал не так:
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
using System;
using System.Xml.Linq;
 
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string test = @"
                           <Body>
                                <UserName>Test</UserName>
                                <ClaimID>CL6555</ClaimID>
                                    <StsRsn>
                                        <Prtry>DD10</Prtry>
                                        <AddStInf>Принят</AddStInf>
                                    </StsRsn>
                           </Body>";
 
            XDocument doc = XDocument.Parse(test);
            foreach (var item in doc.Element("Body").Elements())
            {
                Console.WriteLine($"{item.Name} : {item.Value}");
            }
            Console.ReadKey();
        }
    }
}
Code
1
2
3
4
Результат 
UserName : Test
ClaimID : CL6555
StsRsn : DD10Принят

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Estenity, Вы действительно определитесь более точно что Вам нужно. Просто вывести на консоль определённые элементы, узлы XML?
Создать по XML свой класс, структуру? Если да, то какие? Их свойства, поля и т.д.
Я до этого не понимал как правильно вытаскивать нужные значения с помощью Linq to XML. Сейчас с вашими примерами неплохо разобрался. Планирую засунуть все в некий класс (или есть лучшее решение?) и дальше передавать эти данные с помощью вызовов различных методов (функций и хранимых процедур) в базу
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
22.10.2018, 14:39
Лучший ответ Сообщение было отмечено Estenity как решение

Решение

Цитата Сообщение от Estenity Посмотреть сообщение
Да, планирую засунуть весь результат в модель вида:
C#
1
2
3
4
5
6
7
8
9
10
11
  public class Claim
        {
            public string Sender { get; set; }
            public string Receiver { get; set; }
            public string MsgID { get; set; }
            public DateTime MsgTime { get; set; }
            public char Status { get; set; }
            public string ClaimID { get; set; }
            public string Prtry { get; set; }
            public string AddStInf { 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
        public class Claim
        {
            public string Sender { get; set; }
            public string Receiver { get; set; }
            public string MsgID { get; set; }
            public DateTime MsgTime { get; set; }
            public char Status { get; set; }
            public string ClaimID { get; set; }
            public string Prtry { get; set; }
            public string AddStInf { get; set; }
        }
        static void Main(string[] args)
        {
 
            string test = @"
    <root>
       <sender>TestSender</sender>
       <receiver>TestRec</receiver>
       <type>IN_REC</type>
       <msg_info>
             <response_info>
                    <Header>
                           <MsgId>ARM655655</MsgId>
                           <MsgTime>2018-10-16T17:44:17</MsgTime>
                           <Status>P</Status>
                    </Header>
                    <Body>
                          <UserName>Test</UserName>
                          <ClaimID>CL6555</ClaimID>
                          <StsRsn>
                                  <Prtry>DD10</Prtry>
                                  <AddStInf>Принят</AddStInf>
                       </StsRsn>
                    </Body>
             </response_info>
       </msg_info>
    </root>";
 
            XDocument doc = XDocument.Parse(test);
            XElement root = doc.Element("root");
            XElement Header = root
                .Element("msg_info")
                .Element("response_info")
                .Element("Header");
            XElement Body = root
                .Element("msg_info")
                .Element("response_info")
                .Element("Body");
            XElement StsRsn = Body.Element("StsRsn");
 
            Claim claim = new Claim()
            {
                Sender = root.Element("sender").Value,
                Receiver = root.Element("receiver").Value,
               MsgID  = Header.Element("MsgId").Value,
               MsgTime  = DateTime.Parse( Header.Element("MsgTime").Value),
               Status  = Header.Element("Status").Value[0],
                ClaimID = Body.Element("ClaimID").Value,
                Prtry = StsRsn.Element("Prtry").Value,
                AddStInf = StsRsn.Element("AddStInf").Value
            };
Добавлено через 15 минут
Цитата Сообщение от Estenity Посмотреть сообщение
Не в этом суть, но тогда прошу объяснить, что делал не так:
Суть в моей невнимательности к документации. Моя ошибка. Я был уверен в том, что Value возвращает текст только родительского узла. Надо перепроверить теперь где в прогах его использовал - на возможную ошибку.
Надо так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
            string test = @"
                           <Body>
                                <UserName>Test</UserName>
                                <ClaimID>CL6555</ClaimID>
                                    <StsRsn>Example
                                        <Prtry>DD10</Prtry>
                                        <AddStInf>Принят</AddStInf>
                                    </StsRsn>
                           </Body>";
 
            XDocument doc = XDocument.Parse(test);
            foreach (var item in doc.Element("Body").Elements())
            {
                Console.WriteLine($"{item.Name} : {item.Value}");
                Console.WriteLine($"{item.Name} : {item.Nodes().OfType<XText>().LastOrDefault()}");
            }
            Console.ReadKey();
1
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
22.10.2018, 15:08  [ТС]
Элд Хасп , спасибо! То, что надо.
Остался 1 небольшой вопросик. Как мне вытаскивать именно имя узла (одного).
Т.е имеется наш xml
XML
1
2
3
4
5
6
7
8
<Body>
        <UserName>Test</UserName>
         <ClaimID>CL6555</ClaimID>
         <StsRpt>
              <Prtry>DD10</Prtry>
              <AddStInf>Принят</AddStInf>
          </StsRpt>
</Body>
И я хочу засунуть в обычную локальную переменную, например, имя Body.
При этом:
1) Я, например, знаю, что он имеет имя Body
2) Я только знаю, что он самый верхний по уровню
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
22.10.2018, 15:19
Цитата Сообщение от Estenity Посмотреть сообщение
хочу засунуть в обычную локальную переменную, например, имя Body.
При этом:
1) Я, например, знаю, что он имеет имя Body
Зачем искать имя, если оно уже известно?
0
 Аватар для AlexP11223
141 / 110 / 30
Регистрация: 20.04.2011
Сообщений: 582
22.10.2018, 15:26
Цитата Сообщение от Estenity Посмотреть сообщение
Я только знаю, что он самый верхний по уровню
C#
1
Console.WriteLine(doc.Root.Name);
(применимо аналогично к любым элементам)
1
2 / 2 / 0
Регистрация: 27.11.2015
Сообщений: 36
22.10.2018, 16:10  [ТС]
Цитата Сообщение от AlexP11223 Посмотреть сообщение
(применимо аналогично к любым элементам)
А если я знаю, что он у меня дочерний от самого верхнего и он только 1.
Я понимаю, что есть вариант:
C#
1
2
3
 IEnumerable<string> childNames = xmlDocument.Descendants("Body")
                              .Elements()
                              .Select(e => e.Name.LocalName);
Но это коллекция, а я если я знаю, что он дочерний точно 1.


Цитата Сообщение от amr-now Посмотреть сообщение
Зачем искать имя, если оно уже известно?
Согласен, глупо, не это хотел я
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.10.2018, 16:10
Помогаю со студенческими работами здесь

Создание документа XML через LINQ-to-XML
как создать новый документ xml через LINQ-to-xml XDocument doc =new XDocument(&quot;name.xml&quot;,Encoding.UTF8); ...

Linq to XML парсинг
Доброе утро, уважаемые форумчане, подскажите пожалуйста по Linq: Есть файл XML: &lt;?xml version=&quot;1.0&quot;...

Разбор XML LINQ
есть XML в котором есть такой элемент &lt;N&gt; &lt;I Name=&quot;VASYA&quot; Old=&quot;99&quot; Life=&quot;Moscow&quot;&gt;&lt;/I&gt; &lt;I Name=&quot;Oleg&quot; Old=&quot;88&quot;...

Не работает запрос linq к xml
Пытаюсь распарсить приведенный ниже XML документ. Код не работает, но, если я редактирую XML(удаляю самый первый родительский тег: Orders...

LINQ to XML - поиск по атрибуту
Здравствуйте хотелось бы попросить помощи в одном вопросе. Есть XML файл, записываю в него данные так: XDocument doc = new...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru