Перед многими часто встаёт задача распарсить XML с помощью C#. В данной статье опишу простейшие методы разбора XML без излишней сложности и без подключения библиотек сторонних разработчиков. Описанных примеров хватит для большинства существующих задач.
Создадим в Visual Studio проект Windows Form и набросаем кнопки и текстовые поля и получим примерно такую форму:

По кнопке «Машина» мы будем получать из XML марку, номер и регион, в котором зарегистрирован автомобиль. По кнопке «Страна 2» мы будем получать из XML название второй страны и выводить данные в поле результата. По кнопке «Параметры Страна 1» мы будем получать из XML параметры первой страны (валюта, язык, столица) и выводить данные в поле результата.
Подключим к проекту:
using System; using System.IO; using System.Xml; using System.Windows.Forms;
Объявим пару переменных:
/// <summary> Путь к рабочему каталогу, относительно исполняемого файла </summary> public static string dirWork = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); public static string fileXML = dirWork + @"\XMLFileForParse.xml";
«XMLFileForParse.xml» — это XML-файл который мы будем разбирать, и который имеет следующую структуру:
<?xml version="1.0" encoding="utf-8" ?> <body> <ns2:TransportResponse xmlns:ns2="http://webservices.victorz.ru/"> <TransportName>Газель</TransportName> <TransportNumber>р999вд</TransportNumber> <TransportRegion>77</TransportRegion> </ns2:TransportResponse> <country> <name>Россия</name> <param coin="рубль" language="русский" stolitsa="Москва" /> </country> <country> <name>USA</name> <param coin="usd" language="english" stolitsa="New York" /> </country> </body>
Давайте получим из XML марку автомобиля, номер и регион. Все три значения мы будем получать разными способами, чтобы охватить шире тему. В коде все строки стараюсь комментировать подробно:
/// <summary> private void button2_Click(object sender, EventArgs e) { textBoxResult.Clear(); XmlDocument docXML = new XmlDocument(); docXML.Load(fileXML); string _name = docXML.GetElementsByTagName("TransportName")[0].InnerText; XmlNamespaceManager _namespaceManager = new XmlNamespaceManager(docXML.NameTable); _namespaceManager.AddNamespace("ns2", "http://webservices.victorz.ru/"); string _region = docXML.DocumentElement.SelectNodes("//ns2:TransportResponse/TransportRegion", _namespaceManager)[0].InnerText; string _number = docXML["body"]["ns2:TransportResponse"]["TransportNumber"].InnerText; ; textBoxResult.Text = _name + " - " + _number + " - " + _region; }
У нас в XML есть одинаковые теги «country», «name», «param».
Давайте получим название второй страны, тег «name»:
/// <summary> private void button3_Click(object sender, EventArgs e) { textBoxResult.Clear(); XmlDocument docXML = new XmlDocument(); docXML.Load(fileXML); textBoxResult.Text = docXML.GetElementsByTagName("name")[1].InnerText; textBoxResult.Text = docXML.DocumentElement.SelectNodes("//country/name")[1].InnerText; }
До этого мы получали значения тегов, однако у тегов есть атрибуты. Далее рассмотрим получение значения атрибутов у тега «param». Давайте получим значения атрибутов тега «param» у первой страны:
/// <summary> private void button4_Click(object sender, EventArgs e) { textBoxResult.Clear(); XmlDocument docXML = new XmlDocument(); docXML.Load(fileXML); string _coin = docXML.DocumentElement.SelectNodes("//country/param")[0].Attributes["coin"].Value; string _language = docXML.DocumentElement.SelectNodes("//country/param")[0].Attributes["language"].Value; string _stolitsa = docXML.DocumentElement.SelectNodes("//country/param")[0].Attributes["stolitsa"].Value; textBoxResult.Text = _coin + " - " + _language + " - " + _stolitsa; }
Основы рассмотрели. Надеюсь в работе вам это поможет. Для наглядности приложил пример проекта с расширенными комментариями.
А для Json Есть пример работы??
Сейчас под рукой нет готового решения.
Используйте пакет «Newtonsoft.Json».
Как-нибудь на досуге напишу статью на эту тему.
Спасибо за статью! Мне нужно распарсить служебный файл, там сложная структура, во многом Ваша статья мне помогла. Но вот в одном месте не могу сообразить, как правильно написать. В общем, структура xml допустим такая (упростила)
Т.е. элемент с тегом docdetails встречается в файле несколько раз, но у него разное содержимое. Подскажите, как можно добавить условие, что:
Спасибо заранее!
На скорую такой ответ:
1. Соберите все «kind» и запишите в массив или в список.
2. Определите в цикле какой из них содержит 01. Потом определите его порядковый номер в массиве.
3.1. Если количество тегов «kind» равно количеству тегов «docdetails», то мы сразу узнаем порядковый номер «docdetails» и считаем вложенный в него «number».
3.2. Или соберите все «number» в массив и порядковый номер «number» будет равен порядковому номеру «kind», его мы и считаем.
Если подумать подольше, то можно и ещё варианты подобрать.
ну и задали вы мне задачку, учитывая то, что я чуть ли ни вчера занялась программированием ))) По первому варианту есть вопрос. Допустим я создаю List
и мне нужно добавить значение всех тегов kind в него, но их может быть неограниченное (заранее неизвестное) количество. Вот как мне определить длину массива? Т.е. в данном файле их 3, и, если бы это было бы постоянная величина, то я бы написала так:
У List не надо задавать размер и это поможет, а по поводу реализации надо думать.
Первое что приходит в голову это получить количество «kind» так:
не знаю, не получилось. По первому варианту вроде все срослось с одним файлом, но загрузила другой, а там «kind» вложен также в другой элемент (не только в «docdetails»)
Тогда вам надо определиться какие «kind» вам нужны. Если все, то Count получайте по всем. Если определённые, то Count получайте по примеру выше.
Отличная статья!
Отличная инфа бро! Пили есчо