![C работа с xml извлечение данных. Знакомство с современными средствами работы с XML](https://i0.wp.com/codeby.net/blogs/wp-content/uploads/2016/3/rabota-s-xml-fajlami_10.png)
C работа с xml извлечение данных. Знакомство с современными средствами работы с XML
Представляем вашему вниманию новый курс от команды The Codeby - "Тестирование Веб-Приложений на проникновение с нуля". Общая теория, подготовка рабочего окружения, пассивный фаззинг и фингерпринт, Активный фаззинг, Уязвимости, Пост-эксплуатация, Инструментальные средства, Social Engeneering и многое другое.
XML DOM 2
В предыдущей статье были описаны общие понятия касающиеся XML. В этой статье научимся выполнять основные действия, связанные с изменением, добавлением, поиском в XML файле.
XML файл, который используется для примера.
xml dom
В данный момент, наш файл содержит следующую структуру:
Взаимоотношение между узлами в XML DOM , основные моменты:
1. Любой узел в DOM дереве имеет родителя ParentNode . В нашем примере garage является родителем для обоих элементов car, а оба элемента car, являются в свою очередь родителями для элементов: model и year.
Как получить родителя для xml элемента car?
Console.WriteLine(elmRoot["car"].ParentNode.Name); //Результат: garage
2. У родителя могут быть дети ChildNodes. Например, для узла garage детьми являются оба элемента car. У элементов car, тоже есть дети model и year.
ChildNodes , представляет собой коллекцию, которая хранит все дочерние xml элементы, чтобы обратиться к нужному элементу, нужно указать его индекс. (Индекс всегда начинается с нуля!)
Например: как получить первый дочерний элемент?
ElmRoot.ChildNodes;
3. Как и в обычной жизни ребенок может родиться первым FirstChild, или последним LastChild.
Если взять для примера элемент car, то
FirstChild - это model LastChild - это year
4. В свою очередь между дочерними элементами тоже существуют связи, они могут быть братьями или сестрами, если проводить параллели с реальной жизнью.
У ребенка может быть к примеру брат Previous Sibling и следующий брат Next Sibling
Console.WriteLine(elmRoot.ChildNodes.FirstChild.NextSibling.Name); //Результат: year Console.WriteLine(elmRoot.ChildNodes. LastChild.PreviousSibling.Name); //Результат: model
Если элемент не найден, то тогда возникает исключение: NullReferenceException, поэтому при работе с xml всегда используйте блоки try catch.
Console.WriteLine(elmRoot.ChildNodes. LastChild.NextSibling.Name); Console.WriteLine(elmRoot.ChildNodes. FirstChild.PreviousSibling.Name);
LastChild является NextSibling;
FirstChild является PreviousSibling;
С помощью выше описанных методов можно легко переместиться к нужному узлу и получить любое нужное вам значение.
Как получить значение xml элемента?
Значение xml элемента можно получить при помощи свойства InnerText, например:
Console.WriteLine(elmRoot["car"].FirstChild.InnerText); //Результат: mazda
Ещё один способ, чтобы получить это же значение xml элемента:
Console.WriteLine(elmRoot.FirstChild.FirstChild.InnerText); //Результат: mazda
Последовательность перемещений по DOM дереву:
Garage -> car -> model -> Мазда
Получаем год:
ElmRoot["car"].LastChild.InnerText; //Результат: 2007
Последовательность:
Garage -> car -> year -> 2007
Ещё пример: 3 способа, для получения одного и того же результата.
Console.WriteLine(elmRoot.LastChild.FirstChild.InnerText); Console.WriteLine(elmRoot["car"].NextSibling.FirstChild.InnerText); Console.WriteLine(elmRoot.ChildNodes.Item(1).FirstChild.InnerText); //Результат: BMW
Если надо получить год для элемента со значением Mazda:
Console.WriteLine(elmRoot.FirstChild.LastChild.InnerText); //Результат: 2007
Для BMW (два способа, получить один и тот же результат)
Console.WriteLine(elmRoot.ChildNodes.Item(1). ChildNodes.Item(1).InnerText); Console.WriteLine(elmRoot.ChildNodes.ChildNodes.InnerText); //Результат: 2009
Как изменить значения xml элемента?
С помощью свойства InnerText() можно, как получить, так и изменить значение xml элемента, например изменим год.
//Устанавливаем новое значение elmRoot.FirstChild.LastChild.InnerText = "2010"; //Выводим новое значение на экран консоли Console.WriteLine(elmRoot.FirstChild.ChildNodes.Item(1).InnerText); //Результат: 2010
При этом нужно помнить, что все изменения происходят с виртуальным xml файлом, если Вы откроете физический файл, то увидите, что по-прежнему в нём указан год 2007.
Для того, чтобы изменения вступили в силу, нужно воспользоваться методом Save, например:
ElmRoot.Save("имя xml файла или поток");
Теперь информация будет изменена в «физическом» xml файле.
Как получить количество дочерних элементов?
Console.WriteLine(elmRoot.FirstChild.ChildNodes.Count);garage -> car содержит 2 ребенка: model и year
Console.WriteLine(elmRoot.FirstChild.FirstChild.ChildNodes.Count);
garage -> car -> model содержит 1 дочерний xml элемент.
Обращение к дочерним элементам
по индексу
ElmRoot.ChildNodes.Name; elmRoot.ChildNodes.Name; //Результат: car
С помощью цикла
Foreach (XmlNode nod in elmRoot.ChildNodes) { Console.WriteLine(nod.Name); } //Результат: car, car
Как получить имя xml элемента?
elmRoot.Name; //Результат: garageСоздание нового XML элемента
Создадим новый элемент в нашем XML документе, чтобы он отличался от двух других (car) назовём его автобус (bus).
При создании нового элемента воспользуемся рекомендацией с сайта msdn и вместо стандартного new XmlElement воспользуемся методом CreateElement.
XmlElement elm = xmlDoc.CreateElement("bus");
Создание и добавление нового xml элемента
Создадим новый xml элемент по имени «BUS».
XmlElement elmRoot = xmlDoc.DocumentElement; Console.WriteLine(elmRoot.ChildNodes.Count); //car, car XmlElement elmNew = xmlDoc.CreateElement("bus"); elmRoot.AppendChild(elmNew); Console.WriteLine(elmRoot.ChildNodes.Count); //3 car, car, bus xmlDoc.Save("имя xml файла");Пояснение:
1. Сначала получаем root-элемент к которому будем крепить новые элементы.
2. В качестве проверки выведем текущее количество дочерних элементов у элемента garage: 2 (car и car)
3. Создаем новый элемент BUS
4. При помощи метода AppendChild добавляем новый элемент в дерево
5. Снова воспользуемся проверкой и выведем текущее количество элементов у элемента garage, теперь их стало 3: car, car, bus.
6. Чтобы изменения затронули физический файл, сохраняемся
В самом XML файле новый элемент будет выглядеть так:
Как добавить новый xml элемент?
Задача: создать новый XML элемент и добавить в него какое-нибудь текстовое содержимое, например год выпуска.
String strFilename = @"C:\lessons\Auto.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(strFilename); XmlElement elmRoot = xmlDoc.DocumentElement; XmlElement elmNew = xmlDoc.CreateElement("bus"); XmlText new_txt = xmlDoc.CreateTextNode("2006"); elmRoot.AppendChild(elmNew); elmRoot.LastChild.AppendChild(new_txt); Console.WriteLine(elmRoot.ChildNodes.Name); //bus Console.WriteLine(elmRoot.ChildNodes.LastChild.InnerText); //2006 Console.Read();
В XML файле:
Для наглядности
А теперь создадим узел «bus», с такой же архитектурой, как и car, то есть добавим узлы: model, year и какое-нибудь текстовое содержимое.
Создание XML элемента с дочерними элементами
string strFilename = @"C:\lessons\Auto.xml"; //создаем новый xml документ в памяти XmlDocument xmlDoc = new XmlDocument(); //загружаем xml файл в память xmlDoc.Load(strFilename); //Получаем root-элемент XmlElement elmRoot = xmlDoc.DocumentElement; //Создаём 3 элемента: bus, model, year XmlElement elmBUS = xmlDoc.CreateElement("bus"); XmlElement elmModel = xmlDoc.CreateElement("model"); XmlElement elmYear = xmlDoc.CreateElement("year"); //Устанавливаем значения для элементов: model, year XmlText year_txt = xmlDoc.CreateTextNode("2006"); //XmlText mod_txt = xmlDoc.CreateTextNode("liaz"); добавим иначе //К элементу bus добавляем два дочерних элемента: model и year elmBUS.AppendChild(elmModel); elmBUS.AppendChild(elmYear); //Добавляем значения узлам model и year elmModel.InnerText = "liaz"; elmYear.AppendChild(year_txt); //Добавляем в дерево новый xml элемент bus elmRoot.AppendChild(elmBUS); //Проверяем, всё ли добавлено, как надо Console.WriteLine(elmRoot.ChildNodes.FirstChild.InnerText); Console.WriteLine(elmRoot.LastChild.LastChild.InnerText); //Если всё в порядке, то используем метод Save xmlDoc.Save("имя xml файла");Результат:
Как можно сократить, данный код? Например, следующим образом:
String PathXmlFile = @"C:\lessons\Auto.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(PathXmlFile); XmlElement elmRoot = xmlDoc.DocumentElement; XmlElement elmBUS = xmlDoc.CreateElement("bus"); XmlElement elmModel = xmlDoc.CreateElement("model"); XmlElement elmYear = xmlDoc.CreateElement("year"); //Добавляем значения узлам model и year elmModel.InnerText = "liaz"; elmYear.InnerText = "2006"; elmBUS.AppendChild(elmModel); elmBUS.AppendChild(elmYear); elmRoot.AppendChild(elmBUS); //Если всё верно, то вызываем метод Save xmlDoc.Save("имя xml файла");
Ещё немного сократим код, для этого воспользуемся свойством InnerXml:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(PathXmlFile);
XmlElement elmXML = xmlDoc.CreateElement("bus");
string txt = "
Результат
Получить список элементов при помощи GetElementByTagName
GetElementByTagName возвращает XmlNodeList , в котором содержаться все элементы потомки, принадлежащие указному элементу, например, нам нужно получить все модели машин, которые хранятся в гараже:
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(strFilename); XmlNodeList modelName = xmlDoc.GetElementsByTagName("model"); foreach (XmlNode node in modelName) { Console.WriteLine(node.InnerText); } //Результат: mazda, bmw, liaz
Обращение при помощи индекса:
String PathXmlFile = @"C:\lessons\Auto.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(PathXmlFile); XmlNodeList modelName = xmlDoc.GetElementsByTagName("model"); Console.WriteLine(modelName.InnerText); //Результат: liaz
Как изменить текстовое содержимое, у только что созданного элемента «bus», при помощи метода GetElementByTagName?
String PathXmlFile = @"C:\lessons\Auto.xml"; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(PathXmlFile); XmlNodeList modelName = xmlDoc.GetElementsByTagName("model"); Console.WriteLine(modelName.InnerText); //Получили значение: liaz
Либо можно изменить имя liaz на Ikarus
Console.WriteLine(modelName.InnerText = "Ikarus");
Структуризация данных – вещь полезная, и пригодится в самый неожиданный момент. Например, если структурировать свое ближайшее будущее, то можно увидеть размер своей зарплаты. И можно решить, с какой отдачей проработать весь этот месяц.
Конечно, фантастика, но для структуризации в программировании был придуман специальный язык (xml ). А для редактирования данных, представленных в этом формате, созданы специализированные xml редакторы:
Что такое XML
Многие знают, что основой любого веб-ресурса является HTML . С помощью языка гипертекста можно очень легко и удобно задавать иерархию всех элементов на веб-странице. Частично он позволяет решать проблему и стилевого оформления. Вся эта иерархия создается (структурируется ) с помощью встроенных тегов и их атрибутов, набор которых хоть и не малый, но все же ограниченный.
Поэтому HTML позволяет решать лишь одну единственную задачу структуризации в интернете: расстановки и создания элементов веб-страницы для ее последующей разметки (создания дизайна ). А как же структурировать остальные данные, передаваемые в бесчисленном количестве между ресурсами во всемирной паутине? Как без ограничений организовать их выборку, поиск и фильтрацию?
Все эти «недочеты » могут быть исправлены с помощью XML . Перед началом обзора редакторов xml давайте более подробно разберемся, что это за язык и какова область его применения в виртуальном пространстве:
Аббревиатура XML в переводе с английского означает «расширяемый язык разметки » (Xtensible Markup Language ). Он стандартизирован и рекомендован к использованию W3C . А это значит, что его применение является наиболее оптимальным и «беспроблемным » способом создания веб-документа.
Кроме описания документов XML также частично влияет на работу специальных системных программ. Препроцессоры этого языка предназначены для перевода данных с машинного кода в понятный для пользователя вид. Такие препроцессоры лежат в основе всех редакторов xml файлов.
Язык расширяемой разметки обладает следующими положительными сторонами:
- Является идеальным средством для описания структуры и разметки любого веб-документа;
- В XML нет ограниченного набора элементов, с помощью которых осуществляется структуризация. Вместо этого пользователь сам задает иерархию и имена всех элементов, опираясь лишь на правила описания языка;
- XML обладает простым, понятным, а главное расширяемым синтаксисом;
- Язык построен на основе основных кодировок Юникода;
- Широко применяется не только для описания обычных веб-страниц, но и легко подключается к коду большинства языков программирования. В том числе и тех, которые используются в веб-программировании (PHP, ASP. NET и другие ).
Синтаксис XML
Каждый документ, написанный на XML , состоит из сущностей. Сущность – это самая маленькая единица (элемент ). Каждая из сущностей содержит в себе символы.
Они делятся на:
- Символы разметки — теги, комментарии (< тег>, );
- Буквенные символы – из них состоит основное содержимое, заключенное между тегами.
Логическая структура языка представляет собой иерархически вложенные друг в друга элементы. Самый верхний из них называется корневым. Любой из элементов включает в себя открывающийся и закрывающийся тег. И должен закрываться в том корневом для него элементе, в котором был открыт:
Кроме корневого элемента XML документ состоит из пролога. Он расположен в самом начале кода. В состав пролога могут входить:
- Объявления;
- Инструкции обработки;
- Комментарии.
Более наглядно основные составляющие XML показаны на следующем скриншоте документа, созданного в простом xml редакторе:
Более подробно с синтаксисом языка можно ознакомиться с помощью технической документации к XML .
Обзор редакторов для XML
- Microsoft Visual Studio – представляет собой мощную среду разработки, объединившую в себя большое количество инструментов и средств для написания программного кода. В ее состав также входит «навороченный» редактор XML . Кроме всего прочего он поддерживает создание и визуализацию XML схем. К сожалению, в Visual Studio поддержка PHP реализована слабо. Эта среда больше «заточена » под создание веб-приложений с помощью ASP.NET :
- Adobe Dreamweaver – еще одна мощная среда разработки. Весь ее инструментарий полностью направлен на создание сайтов. Поддерживается синтаксис нескольких языков программирования. В состав Dreamweaver также входит встроенный редактор xml таблиц:
- XMLSpy XML Editor – мощное средство для работы с различными форматами данных XML. Поддерживается не только простое редактирование данных, схем, подсветка синтаксиса, но и графическая визуализация иерархических связей между элементами:
Визуальный xml редактор доступен в двух редакциях стоимостью 399 и 799 евро. Самый дорогой вариант включает в себя поддержку синтаксиса нескольких языков программирования и отладчик. Более дешевый вариант полностью совместим с наиболее популярными средами разработки (Visual Studio, Eclipse ), и может выступать в качестве их полноценной надстройки:
- XML Notepad — бесплатный редактор xml . Имеет встроенную подсветку синтаксиса, средство валидации. А также поддержку построения схем. Приложение отличается простым и понятным интерфейсом:
Обзор онлайн-сервисов
- XML Schema Generator – сервис позволяет из обычного документа XML создать схему (XSD ). Интерфейс сервиса отличается простотой и выполнен в черно-белых тонах. Кроме этого радует полное отсутствие рекламы;
- xmlvalidation.com – данный ресурс позволяет произвести полную валидацию содержимого XML документа, скопированного в специальное поле или загруженного в виде файла:
- XSL Transformation – служит для преобразования обычного XML кода с помощью указанных шаблонов стилей XSLT . Также в состав сервиса входит еще несколько десятков полезных для веб-мастера инструментов, в том числе и онлайн-валидатор XML .
Как видно из обзора, для работы с расширяемым языком разметки лучше всего применять обычный xml редактор, инсталлированный собственный компьютер или ноутбук. Набор инструментов специализированных онлайн-сервисов не так широк, и позволяет лишь проверить код XML документа на валидность. Или преобразовать его содержимое в схему.