С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
1

Как распарсить XML файл?

06.06.2016, 22:16. Просмотров 890. Ответов 22
Метки нет (Все метки)

Добрый вечер всем.
Возникла следующая проблема. Не могу придумать как распарсить XML файл. Можно с помощью регулярок.
Файл следующий:
XML
1
2
3
4
5
6
7
8
9
10
 <?xml version="1.0" encoding="Windows-1251"?>
<Расписание>
<Маршрут>
<НазваниеМаршрут>Номер=1</НазваниеМаршрут>
 
<График><НомерГрафик>Номер=1</НомерГрафик>
<Время>"Окт. депо выход" "51004" "5223" "7:17" "7:19";
"Авиационная (на Саввы Белых)" "5223" "5224" "7:19" "7:21";
"Саввы Белых (на Шварца)" "5224" "941" "7:21" "7:22";
"Шварца (на Самолетную)" "941" "99" "7:22" "7:25";
Это только маленький кусок файла. Дальше идет продолжение тега время, а после повторяется с новым номером графика и номером маршрута. В результате надо получить возможность обращаться к каждой строке тэга Время отдельно. Возможно даже с внутренним вложением.
Буду благодарен за помощь.
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.06.2016, 22:16
Ответы с готовыми решениями:

Как распарсить XML-файл
Вопрос в следующем. Имею xml файл: &lt;?xml version=&quot;1.0&quot;?&gt; &lt;?xml-stylesheet...

Как распарсить Xml-файл
Как тут выдернуть uid first_namе и т.д. XDocument doc =...

Как правильно распарсить xml файл
Здравствуйте. Подскажите пожалуйста . У меня есть файл вот с таким содержанием ...

Как считать и распарсить xml файл
Здраствуйте имеется xml файл &lt;?xml version=&quot;1.0&quot;?&gt; &lt;root&gt; &lt;item...

Как распарсить XML
Привет! Помогите плз выбрать данные из XML файла &lt;Main&gt; ...

22
DataPlanner
153 / 183 / 49
Регистрация: 25.11.2013
Сообщений: 978
06.06.2016, 22:22 2
C#
1
2
XmlDocument doc = new XmlDocument();
doc.Load("c:\\temp.xml");
1
golubyatnikovtv
177 / 177 / 95
Регистрация: 30.04.2016
Сообщений: 478
Завершенные тесты: 3
06.06.2016, 22:34 3
Цитата Сообщение от pro100logik Посмотреть сообщение
Можно с помощью регулярок.
Ни в коем случае!

Чтобы форумчане могли сходу тестировать решения, выкладывайте, пожалуйста, xml с корректной структурой.
1
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
06.06.2016, 22:41  [ТС] 4
Полная структура это около 10к строк)
0
golubyatnikovtv
177 / 177 / 95
Регистрация: 30.04.2016
Сообщений: 478
Завершенные тесты: 3
07.06.2016, 01:05 5
Лучший ответ Сообщение было отмечено pro100logik как решение

Решение

pro100logik, не нужна полная, нужна корректная.

Добавлено через 4 минуты
Т.е. такая

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 <?xml version="1.0" encoding="Windows-1251"?>
<Расписание>
<Маршрут>
<НазваниеМаршрут>Номер=1</НазваниеМаршрут>
 
<График><НомерГрафик>Номер=1</НомерГрафик>
<Время>"Окт. депо выход" "51004" "5223" "7:17" "7:19";
"Авиационная (на Саввы Белых)" "5223" "5224" "7:19" "7:21";
"Саввы Белых (на Шварца)" "5224" "941" "7:21" "7:22";
"Шварца (на Самолетную)" "941" "99" "7:22" "7:25";
</Время>
</График>
</Маршрут>
</Расписание>
Добавлено через 32 минуты
pro100logik,

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
var xml = XDocument.Load("test.xml");
            var routes = xml.Root.Elements("Маршрут")
                .Select(m => new
                {
                    Name = m.Element("НазваниеМаршрут")?.Value,
                    Graphics = m.Elements("График")
                        .Select(g => new
                        {
                            Number = g.Element("НомерГрафик")?.Value,
                            Times = g.Element("Время")?.Value.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                                .Select(t=>t.Trim('\n'))
                                .Where(t=>!string.IsNullOrWhiteSpace(t))
                                .Select(t =>
                                {                                    
                                    // парсим с конца, так как там агрументы не содержат пробелов                                    
                                    var split = string.Join(string.Empty, t.Reverse()).Split(new[] {' '}, 5, StringSplitOptions.RemoveEmptyEntries)
                                        .Select(a=>string.Join(string.Empty, a.Trim('"').Reverse())).Reverse().ToArray();                                    
                                    var time = new
                                    {
                                        Halt = split[0],
                                        Number1 = split[1],
                                        Number2 = split[2],
                                        Time1 = split[3],
                                        Time2 = split[4]
                                    };
                                    return time;
                                }).ToList()
                        }).ToList()
                }).ToList();
2
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
07.06.2016, 20:29  [ТС] 6
golubyatnikovtv, Огромное спасибо. Я к сожалению с листами не очень знаком. Если мне нужен будет еще один тег, несущий дополнительную информацию, похожий на <НомерГрафик>Номер=1</НомерГрафик>, как мне его добавить? И как я после всего этого смогу обращаться к элементам? Буду очень благодарен за объяснение)
0
Rius
Эксперт .NET
5134 / 3353 / 821
Регистрация: 25.05.2015
Сообщений: 10,310
Записей в блоге: 11
Завершенные тесты: 4
07.06.2016, 20:47 7
pro100logik, это чтоли?
XML
1
2
3
<График номер="1">
   ...
</График>
0
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
07.06.2016, 20:49  [ТС] 8
Rius, нет. Такого типа
XML
1
<Транспорт>Автобус</Транспорт>
И надо ли что-то дополнительно прописывать? Ибо у меня он ругается на . перед Value и на вот этот кусок
C#
1
Value.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
с ошибкой "Неверное определение члена анонимного типа. Члены анонимного типа должны быть объявлены присваиванием члена, простым именем или доступом к члену. "
0
Rius
Эксперт .NET
5134 / 3353 / 821
Регистрация: 25.05.2015
Сообщений: 10,310
Записей в блоге: 11
Завершенные тесты: 4
07.06.2016, 20:51 9
pro100logik, структуру домумента сами составляете, или готовое откуда-то выдано?
0
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
07.06.2016, 20:55  [ТС] 10
Rius, к сожалению готовое. Поэтому много беспутых тегов(
0
Rius
Эксперт .NET
5134 / 3353 / 821
Регистрация: 25.05.2015
Сообщений: 10,310
Записей в блоге: 11
Завершенные тесты: 4
07.06.2016, 21:15 11
Цитата Сообщение от pro100logik Посмотреть сообщение
ругается на . перед Value
C#
1
?.
- null-условный оператор, добавлен в C# 6.0.

Цитата Сообщение от pro100logik Посмотреть сообщение
<Транспорт>Автобус</Транспорт>
Пример покажите.

Цитата Сообщение от pro100logik Посмотреть сообщение
к сожалению с листами не очень знаком
Лист тут - не проблема. Дело в Linq и Linq to Xml.
Литература по C# для начинающих и не только
Шилдт - глава 19 (Linq),
Троелсен - главы 12 (Linq) и 24 (Linq to Xml).
1
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
07.06.2016, 21:35  [ТС] 12
Цитата Сообщение от Rius Посмотреть сообщение
- null-условный оператор, добавлен в C# 6.0.
придется ставить новую VS) ну ниче, давно 15 хотел.
Цитата Сообщение от Rius Посмотреть сообщение
Пример покажите.
дак это и есть пример)
За литературу отдельное спасибо.
0
Rius
Эксперт .NET
5134 / 3353 / 821
Регистрация: 25.05.2015
Сообщений: 10,310
Записей в блоге: 11
Завершенные тесты: 4
07.06.2016, 21:51 13
Цитата Сообщение от pro100logik Посмотреть сообщение
Если мне нужен будет еще один тег, несущий дополнительную информацию, похожий на <НомерГрафик>Номер=1</НомерГрафик>, как мне его добавить?
Пример, куда добавить, к какому другому тегу. Транспорта нет нигде.
И куда его выводить.

Ещё вариант - привести программно этот недо-xml к аккуратному виду. Потом обрабатывать его с более простым Linq to Xml. Если, конечно, не требуется его передавать в обе стороны.
0
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
07.06.2016, 22:07  [ТС] 14
Rius, Переделать увы не получится, ибо поступает он извне именно в этом виде.
а пример вот
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 <?xml version="1.0" encoding="Windows-1251"?>
<Расписание>
<Маршрут>
<НазваниеМаршрут>Номер=1</НазваниеМаршрут>
<Транспорт>Автобус</Транспорт>
 
<График><НомерГрафик>Номер=1</НомерГрафик>
<Время>"Окт. депо выход" "51004" "5223" "7:17" "7:19";
"Авиационная (на Саввы Белых)" "5223" "5224" "7:19" "7:21";
"Саввы Белых (на Шварца)" "5224" "941" "7:21" "7:22";
"Шварца (на Самолетную)" "941" "99" "7:22" "7:25";
</Время>
</График>
</Маршрут>
</Расписание>
0
golubyatnikovtv
177 / 177 / 95
Регистрация: 30.04.2016
Сообщений: 478
Завершенные тесты: 3
07.06.2016, 23:01 15
Цитата Сообщение от pro100logik Посмотреть сообщение
Если мне нужен будет еще один тег, несущий дополнительную информацию, похожий на <НомерГрафик>Номер=1</НомерГрафик>, как мне его добавить?
Вы XML менять хотите? Он же извне поступает. Куда добавлять собираетесь?
0
pro100logik
0 / 0 / 0
Регистрация: 05.01.2012
Сообщений: 25
07.06.2016, 23:19  [ТС] 16
golubyatnikovtv, В моем полном XML файлике больше тегов. ТО что я скинул это урезанная версия дабы не захламлять. Может я и зря так сделал)
И скстати, подскажите как мне сейчас обращаться к полученным файлам, а то я не совсем понимаю?
0
Rius
Эксперт .NET
5134 / 3353 / 821
Регистрация: 25.05.2015
Сообщений: 10,310
Записей в блоге: 11
Завершенные тесты: 4
08.06.2016, 08:51 17
Цитата Сообщение от pro100logik Посмотреть сообщение
Переделать увы не получится, ибо поступает он извне именно в этом виде.
При поступлении переделать же, на стороне получателя.

Добавлено через 4 часа 2 минуты
Пример:
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
XDocument src = XDocument.Parse(Resources.source);
 
Func<string, XElement> convertTime = sourceTime =>
    {
        var strings = sourceTime
            .Split(new char[] { ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)
            .Select(x => x.Trim())
            .Where(x => !String.IsNullOrWhiteSpace(x));
 
        return new XElement("times",
            strings.Select(str => str.Trim())
                .Select(str =>
                {
                    var parts = str
                        .Split(new string[] { "\" \"" }, 5, StringSplitOptions.RemoveEmptyEntries)
                        .Select(x => x.Trim('\"', ' '))
                        .ToArray();
                    return new XElement("stop",
                        new XAttribute("name", parts[0]),
                        new XAttribute("id1", parts[1]),
                        new XAttribute("id2", parts[2]),
                        new XAttribute("time1", parts[3]),
                        new XAttribute("time2", parts[4]));
                }));
    };
 
Func<XElement, XElement> convertTimeTable = sourceTimeTable =>
    {
        return new XElement("timetable",
            new XAttribute("number", ((string)sourceTimeTable.Element("НомерГрафик")).Replace("Номер=", "")),
            convertTime((string)sourceTimeTable.Element("Время")));
    };
 
Func<XElement, XElement> convertRoute = sourceRoute =>
    {
        return new XElement("route",
            new XAttribute("name", ((string)sourceRoute.Element("НазваниеМаршрут")).Replace("Номер=", "")),
            sourceRoute.Elements("График").Select(x => convertTimeTable(x)));
    };
 
XDocument dest = new XDocument(
    new XDeclaration("1.0", "UTF-8", null),
    new XElement("schedule",
        src.Root.Elements("Маршрут").Select(x => convertRoute(x))));
преобразует
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="windows-1251"?>
<Расписание>
  <Маршрут>
    <НазваниеМаршрут>Номер=1</НазваниеМаршрут>
    <График>
      <НомерГрафик>Номер=1</НомерГрафик>
      <Время>
        "Окт. депо выход" "51004" "5223" "7:17" "7:19";
        "Авиационная (на Саввы Белых)" "5223" "5224" "7:19" "7:21";
        "Саввы Белых (на Шварца)" "5224" "941" "7:21" "7:22";
        "Шварца (на Самолетную)" "941" "99" "7:22" "7:25";
      </Время>
    </График>
  </Маршрут>
</Расписание>
в
XML
1
2
3
4
5
6
7
8
9
10
11
12
<schedule>
  <route name="1">
    <timetable number="1">
      <times>
        <stop name="Окт. депо выход" id1="51004" id2="5223" time1="7:17" time2="7:19" />
        <stop name="Авиационная (на Саввы Белых)" id1="5223" id2="5224" time1="7:19" time2="7:21" />
        <stop name="Саввы Белых (на Шварца)" id1="5224" id2="941" time1="7:21" time2="7:22" />
        <stop name="Шварца (на Самолетную)" id1="941" id2="99" time1="7:22" time2="7:25" />
      </times>
    </timetable>
  </route>
</schedule>
1
golubyatnikovtv
177 / 177 / 95
Регистрация: 30.04.2016
Сообщений: 478
Завершенные тесты: 3
08.06.2016, 10:02 18
Rius, на мой взгляд, это лишняя работа. Зачем вводить промежуточный xml?

pro100logik, ознакомьтесь с материалами по Linq и Linq to XML которые предложил товарищ Rius.
Чтение дополнительного тега не составляет никакого труда, делается это абсолютно так же как и с теми тегами, которые читаются в свойства объектов в показанном выше примере. Т.е. в зависимости от расположения тега нужно будет добавить в Linq запрос еще одно свойство как то так
C#
1
Transport = g.Element("Транспорт")?.Value
Т.к. я не знаю где этот тег находится, я не могу подсказать куда это свойство нужно добавить в запрос.
1
Rius
Эксперт .NET
5134 / 3353 / 821
Регистрация: 25.05.2015
Сообщений: 10,310
Записей в блоге: 11
Завершенные тесты: 4
08.06.2016, 10:10 19
golubyatnikovtv, лишняя, если дальше ничего делать не надо и за пределы функции var не передавать. Если же будет дальнейшая обработка, она упростится с нормальным xml.
0
golubyatnikovtv
177 / 177 / 95
Регистрация: 30.04.2016
Сообщений: 478
Завершенные тесты: 3
08.06.2016, 11:00 20
Rius, если нужно передавать за пределы функции, то от анонимных типов следует избавиться и описать классы. Дальнейшую работу лучше производить не с xml-ем (даже нормальным), а с объектами.
2
08.06.2016, 11:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.06.2016, 11:00

Как распарсить XML
Добрый день:) все никак не понимаю, как из xml брать элементы, вот такого вида:...

Как распарсить xml
Собственно: &lt;?php $request .= '&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;'; ...

Как распарсить определенную строку в XML
Вот xml: 1 СТРОКА &lt;Object Angles=&quot;0,-0,-140&quot; dir=&quot;130&quot; Ignore_heightcheck=&quot;0&quot;...


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

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

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