Работа с XML в.NET-приложениях. Знакомство с современными средствами работы с XML

В первой статье в блоге .NET «Работаем с XML » в комментариях народ потребовал статьи LINQ to XML. Что же, попробуем раскрыть принципы работы этой новой технологии от Microsoft.

Создадим базу для ведения каталога аудиозаписей. База будет состоять из треков:

  • Название
  • Исполнитель
  • Альбом
  • Продолжительность
Мы научимся добавлять, редактировать, удалять и делать различные выборки из нашей базы.

Для начала создадим консольное приложение (я пишу свои проекты на C#, но суть в общем-то понятна будет всем) и подключим необходимое пространство имен

Using System.Xml.Linq;

Создание файлов XML

Создадим XML файл нашей базы содержащий несколько тестовых записей уже при помощи LINQ:

//задаем путь к нашему рабочему файлу XML string fileName = "base.xml"; //счетчик для номера композиции int trackId = 1; //Создание вложенными конструкторами. XDocument doc = new XDocument(new XElement("library", new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Rap"), new XAttribute("time", "3:24"), new XElement("name", "Who We Be RMX (feat. 2Pac)"), new XElement("artist", "DMX"), new XElement("album", "")), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Rap"), new XAttribute("time", "5:06"), new XElement("name", "Angel (ft. Regina Bell)"), new XElement("artist", "DMX"), new XElement("album", "...And Then There Was X")), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Break Beat"), new XAttribute("time", "6:16"), new XElement("name", "Dreaming Your Dreams"), new XElement("artist", "Hybrid"), new XElement("album", "Wide Angle")), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Break Beat"), new XAttribute("time", "9:38"), new XElement("name", "Finished Symphony"), new XElement("artist", "Hybrid"), new XElement("album", "Wide Angle")))); //сохраняем наш документ doc.Save(fileName);

Теперь в папке с нашей программой после запуска появится XML файл следующего содержания:
Who We Be RMX (feat. 2Pac) DMX The Dogz Mixtape: Who"s Next?! Angel (ft. Regina Bell) DMX ...And Then There Was X Dreaming Your Dreams Hybrid Wide Angle Finished Symphony Hybrid Wide Angle

Для создания подобного файла средствами XmlDocument кода понадобилось где-то раза в 2 больше. В коде выше мы воспользовались конструктором класса XDocument, который принимает в качестве параметра перечень дочерних элементов, которыми мы изначально хотим инициализировать документ. Используемый конструктор XElement принимает в качестве параметра имя элемента, который мы создаем, а так же перечень инициализирующих элементов. Удобно то, что мы в этих элементах можем задавать как новые XElement, так и XAttribute. Последние отрендретятся в наш файл как атрибуты самостоятельно. Если вам не нравится использоваться такую вложенность конструкторов и вы считаете такой код громоздким, то можно переписать в более традиционный вариант. Код ниже даст на выходе аналогичный XML файл:

XDocument doc = new XDocument(); XElement library = new XElement("library"); doc.Add(library); //создаем элемент "track" XElement track = new XElement("track"); //добавляем необходимые атрибуты track.Add(new XAttribute("id", 1)); track.Add(new XAttribute("genre", "Rap")); track.Add(new XAttribute("time", "3:24")); //создаем элемент "name" XElement name = new XElement("name"); name.Value = "Who We Be RMX (feat. 2Pac)"; track.Add(name); //создаем элемент "artist" XElement artist = new XElement("artist"); artist.Value = "DMX"; track.Add(artist); //Для разнообразия распарсим элемент "album" string albumData = "The Dogz Mixtape: Who"s Next?!"; XElement album = XElement.Parse(albumData); track.Add(album); doc.Root.Add(track); /* *остальные элементы добавляем по аналогии */ //сохраняем наш документ doc.Save(fileName);

Естественно выбирать необходимый способ нужно по ситуации.

Чтение данных из файла

//задаем путь к нашему рабочему файлу XML string fileName = "base.xml"; //читаем данные из файла XDocument doc = XDocument.Load(fileName); //проходим по каждому элементу в найшей library //(этот элемент сразу доступен через свойство doc.Root) foreach (XElement el in doc.Root.Elements()) { //Выводим имя элемента и значение аттрибута id Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value); Console.WriteLine(" Attributes:"); //выводим в цикле все аттрибуты, заодно смотрим как они себя преобразуют в строку foreach (XAttribute attr in el.Attributes()) Console.WriteLine(" {0}", attr); Console.WriteLine(" Elements:"); //выводим в цикле названия всех дочерних элементов и их значения foreach (XElement element in el.Elements()) Console.WriteLine(" {0}: {1}", element.Name, element.Value); }

Здесь в коде, думаю, ничего сложного нету и приведены комментарии. После запуска нашей программый в консоли отобразится следующий результат:

Track 1 Attributes: id="1" genre="Rap" time="3:24" Elements: name: Who We Be RMX (feat. 2Pac) artist: DMX album: The Dogz Mixtape: Who"s Next?! track 2 Attributes: id="2" genre="Rap" time="5:06" Elements: name: Angel (ft. Regina Bell) artist: DMX album: ...And Then There Was X track 3 Attributes: id="3" genre="Break Beat" time="6:16" Elements: name: Dreaming Your Dreams artist: Hybrid album: Wide Angle track 4 Attributes: id="4" genre="Break Beat" time="9:38" Elements: name: Finished Symphony artist: Hybrid album: Wide Angle

Изменение данных

Попробуем пройтись по всем узлам library и увеличить аттрибут Id элемента track на 1.
(дальше писать объявление пути к файлу и результат вывода в консоль я приводить не буду, чтобы не перегружать лишней информацией статью, все компилировал, все работает:)) :

//Получаем первый дочерний узел из library XNode node = doc.Root.FirstNode; while (node != null) { //проверяем, что текущий узел - это элемент if (node.NodeType == System.Xml.XmlNodeType.Element) { XElement el = (XElement)node; //получаем значение аттрибута id и преобразуем его в Int32 int id = Int32.Parse(el.Attribute("id").Value); //увеличиваем счетчик на единицу и присваиваем значение обратно id++; el.Attribute("id").Value = id.ToString(); } //переходим к следующему узлу node = node.NextNode; } doc.Save(fileName);

Теперь попробуем это сделать более правильным способом для наших задач:

Foreach (XElement el in doc.Root.Elements("track")) { int id = Int32.Parse(el.Attribute("id").Value); el.SetAttributeValue("id", --id); } doc.Save(fileName);

Как видим – этот способ нам подошел больше.

Добавление новой записи

Добавим новый трек в нашу библиотеку, а заодно вычислим средствами LINQ следующий уникальный Id для трека:

Int maxId = doc.Root.Elements("track").Max(t => Int32.Parse(t.Attribute("id").Value)); XElement track = new XElement("track", new XAttribute("id", ++maxId), new XAttribute("genre", "Break Beat"), new XAttribute("time", "5:35"), new XElement("name", "Higher Than A Skyscraper"), new XElement("artist", "Hybrid"), new XElement("album", "Morning Sci-Fi")); doc.Root.Add(track); doc.Save(fileName);

Вот таким подним запросом ко всем элементам вычисляется максимальное значение аттрибута id у треков. При добавлении полученное максимальное значение инкрементируем. Само же добавление элемента сводится к вызову метода Add. Обратите внимание, что добавляем элементы в Root, так как иначе нарушим структуру XML документа, объявив там 2 корневых элемента. Так же не забывайте сохранять ваш документ на диск, так как до момента сохранения никакие изменения в нашем XDocument не отразятся в XML файле.

Удаление элементов

Попробуем удалить все элементы исполнителя DMX:

IEnumerable tracks = doc.Root.Descendants("track").Where(t => t.Element("artist").Value == "DMX").ToList(); foreach (XElement t in tracks) t.Remove();

В этом примере мы вначале выбрали все треки у который дочерний элемент artst удовлетворяет критерии, а потом в цикле удалили эти элементы. Важен вызов в конце выборки ToList(). Этим самым мы фиксируем в отдельном участке памяти все элементы, которые хотим удалить. Если же мы надумаем удалять из набора записей, по которому проходим непосредственно в цикле, мы получим удаление первого элемента и последующий NullReferenceException. Так что важно помнить об этом.
По совету xaoccps удалять можно и более простым способом:
IEnumerable tracks = doc.Root.Descendants("track").Where(t => t.Element("artist").Value == "DMX"); tracks.Remove();
В этом случае приводить к списку наш полученный результат вызовом функции ToList() не нужно. Почему этот способ не использовал изначально описал в

Последнее обновление: 31.10.2015

Для работы с XML в C# можно использовать несколько подходов. В первых версиях фреймворка основной функционал работы с XML предоставляло пространство имен System.Xml . В нем определен ряд классов, которые позволяют манипулировать xml-документом:

    XmlNode : представляет узел xml. В качестве узла может использоваться весь документ, так и отдельный элемент

    XmlDocument : представляет весь xml-документ

    XmlElement : представляет отдельный элемент. Наследуется от класса XmlNode

    XmlAttribute : представляет атрибут элемента

    XmlText : представляет значение элемента в виде текста, то есть тот текст, который находится в элементе между его открывающим и закрывающим тегами

    XmlComment : представляет комментарий в xml

    XmlNodeList : используется для работы со списком узлов

Ключевым классом, который позволяет манипулировать содержимым xml, является XmlNode , поэтому рассмотрим некоторые его основные методы и свойства:

    Свойство Attributes возвращает объект XmlAttributeCollection , который представляет коллекцию атрибутов

    Свойство ChildNodes возвращает коллекцию дочерних узлов для данного узла

    Свойство HasChildNodes возвращает true , если текущий узел имеет дочерние узлы

    Свойство FirstChild возвращает первый дочерний узел

    Свойство LastChild возвращает последний дочерний узел

    Свойство InnerText возвращает текстовое значение узла

    Свойство InnerXml возвращает всю внутреннюю разметку xml узла

    Свойство Name возвращает название узла. Например, - значение свойства Name равно "user"

    Свойство ParentNode возвращает родительский узел у текущего узла

Применим эти классы и их функционал. И вначале для работы с xml создадим новый файл. Назовем его users.xml и определим в нем следующее содержание:

Microsoft 48 Google 42

Теперь пройдемся по этому документу и выведем его данные на консоль:

Using System.Xml; class Program { static void Main(string args) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("users.xml"); // получим корневой элемент XmlElement xRoot = xDoc.DocumentElement; // обход всех узлов в корневом элементе foreach(XmlNode xnode in xRoot) { // получаем атрибут name if(xnode.Attributes.Count>0) { XmlNode attr = xnode.Attributes.GetNamedItem("name"); if (attr!=null) Console.WriteLine(attr.Value); } // обходим все дочерние узлы элемента user foreach(XmlNode childnode in xnode.ChildNodes) { // если узел - company if(childnode.Name=="company") { Console.WriteLine("Компания: {0}", childnode.InnerText); } // если узел age if (childnode.Name == "age") { Console.WriteLine("Возраст: {0}", childnode.InnerText); } } Console.WriteLine(); } Console.Read(); } }

В итоге я получу следующий вывод на консоли:

Чтобы начать работу с документом xml, нам надо создать объект XmlDocument и затем загрузить в него xml-файл: xDoc.Load("users.xml");

При разборе xml для начала мы получаем корневой элемент документа с помощью свойства xDoc.DocumentElement . Далее уже происходит собственно разбор узлов документа.

В цикле foreach(XmlNode xnode in xRoot) пробегаемся по всем дочерним узлам корневого элемента. Так как дочерние узлы представляют элементы , то мы можем получить их атрибуты: XmlNode attr = xnode.Attributes.GetNamedItem("name"); и вложенные элементы: foreach(XmlNode childnode in xnode.ChildNodes)

Чтобы определить, что за узел перед нами, мы можем сравнить его название: if(childnode.Name=="company")

Подобным образом мы можем создать объекты User по данным из xml:

List users = new List(); XmlDocument xDoc = new XmlDocument(); xDoc.Load("users.xml"); XmlElement xRoot = xDoc.DocumentElement; foreach(XmlElement xnode in xRoot) { User user = new User(); XmlNode attr = xnode.Attributes.GetNamedItem("name"); if (attr!=null) user.Name=attr.Value; foreach (XmlNode childnode in xnode.ChildNodes) { if (childnode.Name == "company") user.Company=childnode.InnerText; if (childnode.Name == "age") user.Age = Int32.Parse(childnode.InnerText); } users.Add(user); } foreach (User u in users) Console.WriteLine("{0} ({1}) - {2}", u.Name, u.Company, u.Age);

Представляем вашему вниманию новый курс от команды The Codeby - "Тестирование Веб-Приложений на проникновение с нуля". Общая теория, подготовка рабочего окружения, пассивный фаззинг и фингерпринт, Активный фаззинг, Уязвимости, Пост-эксплуатация, Инструментальные средства, Social Engeneering и многое другое.


XML DOM 2

В предыдущей статье были описаны общие понятия касающиеся XML. В этой статье научимся выполнять основные действия, связанные с изменением, добавлением, поиском в XML файле.

XML файл, который используется для примера.

Mazda 2007 BMW 2009

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 файле:

2006

Для наглядности

А теперь создадим узел «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 файла");

Результат:

liaz 2006

Как можно сократить, данный код? Например, следующим образом:

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 = "liaz" + "2006"; //InnerXml! elmXML.InnerXml = txt; //xmlDoc.DocumentElement (будет равен garage) - это ещё один способ обратиться к root-элементу, тоже самое что и XmlElement elmRoot = xmlDoc.DocumentElement; xmlDoc.DocumentElement.AppendChild(elmXML); xmlDoc.Save(PathXmlFile);

Результат

Получить список элементов при помощи 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 расшифровывается как Extensible Markup Language, в переводе «расширяемый язык разметки». Как и язык HTML, он является подмножеством SGML (Standard General Markup Language) - «дедушки» языков разметки. Мы уже не раз сталкивались с форматом XML. Таков формат конфигурационных файлов, файла описания объектных источников данных.

XML - это универсальный, независящий от платформы стандарт описания информациии, который можно использовать для представления иерархических данных и унификации передаваемой информации. Без его знания невозможно понимание SOAP и следовательно, веб-сервисов. XML стал де-факто стандартом передачи данных в сети Интернет. Стандарт XML и связанных с ним форматов определяется консорциумом W3C(World Wide Web Consortium). Например, мы создаем aspx страницы в формате XHTML - переходном между HTML и XML, стандарт которого тоже определен W3C. Стандарт XHTML налагает более строгие правила на правильное формирование документа, аналогичные правилам XML.

Давайте поймем главное отличие XML от HTML. XML создан для описания данных и фокусируется на том, что именно они из себя представляют. HTML создан для демонстрации данных и фокусируется на том, как данные выглядят. Если в традиционном HTML понятия «представление» и «визуализация» часто смешиваются, то при работе с XML мы четко разделяем эти понятия. Теги XML не предопределены создателями языка, в отличие от тегов HTML. Каждый автор документа сам определяет собственные теги.

Стандарт требует, чтобы программа, которая обрабатывает XML-документ, должна остановить работу, если обнаружила ошибку. А если браузер обнаружит непонятный тег в HTML, или отсутствие закрывающего тега, он это просто игнорирует.

В начале XML-документа обязательно появляется его декларация, или пролог. В нем указывается версия стандарта XML, которому он соответствует.

является ошибкой в XML.

У тегов могут быть атрибуты. Значения атрибутов должны быть заключены в кавычки. Порядок атрибутов значения не имеет. Между открывающим и закрывающими тегами может находится текст. В XML сохраняются все пробелы, находящиеся в тексте. Если текста нет, можно применить сокращенную форму записи. Пример тега XML:

Это краткая форма тега

Вам это ничего не напоминает? Правила описания элементов ASP.NET точно такие же.

Существует атрибут xmlns, который определяет пространство имен. Значением его может быть любое уникальное имя. Существует договоренность использовать URL, так как они уникальны. Пространства имен имеют смысл, аналогичный их применению в.NET Framework - чтобы не смешивать одинаковые имена, используемые разными разработчиками. Название пространства имен отделяется от имени двоеточием.

XML-файлы представляют иерархическую информацию, которую можно представить в виде дерева с одним корнем.

Документы XML, удовлетворяющие всем требованиям синтаксиса, называют правильными (well-formed). Для описания данных XML использует DTD (Document Type Definition) - определение типа документа. Если файл соответствует DTD, он считается действительным (valid) .

Браузеры IE 6.0, FireFox 1.5 отображают XML-файлы с выделением синтаксиса. Родительские узлы можно раскрывать и закрывать. Например, в закрытом виде корневой узел файла BirthDay.xml выглядит так:

Среды разработки Visual Studio и VWD Express проверяют правильность xml-документов прямо во время редактирования.

AdRotator

Элемент управления AdRotator позволяет показывать рекламные баннеры и автоматически заменять их на другие. Сами баннеры описаны в файле XML или другом источнике данных. Реклама обновляется каждый раз при обновлении страницы. В свойстве AdvertismentFile задается имя XML-файла. Скелет XML-файла таков.

Внутри узла Advertisements располагаются узлы

У этих узлов имеются 5 атрибутов, все они необязательны.

Пример файла AdvertismentFile, он называется ads.xml.

fixed.gif http://www.im.am Бесплатный хостинг 40 хостинг logo2.jpg http://www.nv.am Газета "Новое время" 50 новости summer.jpg http://www.utro.ru Певицу Жасмин избил муж! 100 желтые новости

На страницу помещен элемент управления. Его свойство AdvertisementFile указывает на этот файл.

Если установлено свойство Keyword, то элемент управления показывает только ту рекламу, которая соответствует его содержанию. Так как его можно менять динамически, можно подстраивать рекламу под нужды пользователя. Keyword должен встречаться хотя бы раз в файле объявлений, иначе вместо рекламы будет пустой прямоугольник.

В предыдущих версиях ASP.NET можно было работать только с файлами XML. Теперь можно использовать любой источник данных, связавшись с элементом управления-источником данных. В таком случае необходимо указать как минимум 3 поля источника в свойствах ImageUrlField, NavigateUrlField и AlternateTextField.

Файлы преобразования документа

Известно, что для форматирования HTML-файлов часто используются CSS (Cascading Stylesheets), хотя это необязательно, так как браузеры соотносят со всеми тегами определенный внешний вид. Элемент

Задает параграф, - полужирный шрифт - браузер знает, как их показывать.

Поскольку XML не использует изначально заданные теги, их значение может быть каким угодно:

может означать таблицу HTML, а может и деревянный стол. Поэтому браузеры показывают XML-документы «как есть». Можно задать CSS файлы и для XML-документов, но это не рекомендуется.

Для того, чтобы задать формат отображения XML-документов, используются таблицы стилей XSL . XSL - расширяемый язык стилей (Extensible Stylesheet Language) гораздо более богат возможностями, чем CSS. XSL - больше, чем просто таблица стилей.

Один и тот же файл XML можно связать с разными таблицами XSL, в том числе программно.

XSL состоит из 3 частей:

  1. XSLT - метода преобразования XML-документов
  2. XPath - метода задания частей и путей к элементам XML
  3. XSL Formatting Objects - метода форматирования XML-документов

Самая важная часть XSL - это язык преобразований XSLT (XSL Transformation). Он применяется для преобразования XSL-документов в другие типы документов или другие XSL -документы. Часто XSLT используется для преобразования XSL-документа в формат HTML.

Для того, чтобы создать XSLT-документ, выберите в диалоге создания файла XSLT file. VS 2005 создает каркас таблицы стилей. Так как таблица стилей сама по себе является XML-документом, она начинается с декларации XML.

Если вы изучали CSS, то знаете, что для задания стилей используются правила. Правило состоит из селектора и описания стиля в фигурных скобках.

В этот тег вложен шаблон HTML -файла. Комментарий напоминает о том, что туда нужно вставить XSL-элементы.

Создание файлов XSLT рассмотрим на примере. Создайте в папке App_Data файл XML "Quotes.xml"

Хотели как лучше, а получилось как всегда. Виктор Черномырдин Америка - континент, названный так потому, что его открыл Колумб. Жорж Элгози Я прихожу в бешенство от одной мысли о том, сколько бы я всего узнал, если бы не ходил в школу. Джордж Бернард Шоу Многое придумано для того, чтобы не думать. Карел Чапек Если скажешь правду, все равно рано или позно попадешься. Оскар Уайльд Быть ему президентом, если его до той поры не повесят. Марк Твен

Чтобы внести в выходной поток XSLT-преобразования каждый XML-элемент, применяется тег XSL xsl:for-each. Элемент:for-each определяет местоположение элементов в XML-документе и повторяет шаблон для каждого из них.

Данные можно отсортировать с помощью тега xsl:sort, который должен находиться внутри элемента xsl:for-each:

Окончательный вид файла трансформации:

Известные цитаты

Цитата Автор

Если хотите увидеть результат преобразования документа в браузере, включите после XML-декларации объявление

,

или выберите в меню XML пункт Show XML Output и определите файл преобразования.

Тот же самый XML-документ можно преобразовать с помощью другого XSL-файла:

Мастера Афоризма



В результате будет выводиться цитаты, разделенные горизонтальной линией.

Файлы определения схемы документа

Согласно современному стандарту, валидный документ должен соответствовать связанному с ним файлу XSD (XML Schema Definition) - файлу определения схемы XML, который определяет конкретный язык, то есть описывает, какие элементы и типы могут появляться в документе. Схемы XSD призваны заменить DTD (Document Type Definition), разница между ними заключается в том, что файлы XSD сами тоже используют синтаксис XML. Схемы XSD позволяют определить, какие теги разрешены, обязательны они или нет, могут ли повторяться в документе и так далее. Таким образом, XML описывает данные, а XSD - структуру этих данных, или метаданные. В терминах программирования, XSD - описание типов, в то время как в XML-файле описаны объекты этих типов. По адресу http://www.w3.org/TR/2003/WD-xmlschema-11-req-20030121/ находится рабочий проект стандарта XSD 1.1.

Файл описания схемы начинается с описания префикса пространства имен, который включается затем во все элементы этого файла. Адрес http://tempuri.org предназначается для задания URI для пространств имен ASP.NET .

Например, это определение задает, что элемент "Author" строкового типа, должен появляться один и только один и раз, и если он не указан, то принимает значение "Пушкин".

Параметр maxOccurs="unbounded" указывает, что элемент может встречаться любое количество раз.

Параметр ref позволяет ссылаться на уже описанный в данном файле глобальный элемент или атрибут, чтобы избежать повторного описания одних и тех же элементов.

  1. определить простые и сложные типы.

В XSD есть предопределенные типы - примерно такие же, как в.NET. Во время работы приложения они преобразуются в типы.NET. На их основании можно строить сложные типы, похожие на структуры языков программирования. Сложный тип состоит из последовательности описаний элементов. Определим сложный тип

Тег определяет, что элементы в данном типе должны появляться в заданном порядке. Если бы использовался тег , то элементы могли бы появляться в любом порядке.

Тег похож на структуру с вариантами. Он определяет, что в элементе данног типа должен быть только один из вложенных элементов.

В следующем примере определен простой тип, вложенный в определение элемента MyValue.

  1. Добавлять новые группы и группы атрибутов.

В определении сложного типа могут фигурировать атрибуты. Предположим, мы хотим построить схему такого файла:

Атрибуты могут быть только простых типов.

  1. Добавлять аннотации.

Аннотации позволяют вставлять описание существующих элементов, таким образом в файл добавляется документация.

Цитаты разных авторов

предназначается для читателей файла, а для обрабатывающих файл программ.

Редактировать XSD-файлы в Visual Studio 2005 можно и через исходный код, и с помощью дизайнера. Для XML-документа можно автоматически сгенерировать соответсвующую ему схему. В окне свойств XML-документа можно задать как файл схемы, так и файл преобразования. В таком случае студия автоматически проверяет файл на соответствие схеме, и даже IntelliSense подставляет теги из этого файла.

Класс XmlReader

С помощью класса XmlReader можно быстрее, чем другими методами, получить данные из XML-документов.

XmlReader - это абстрактный класс. Чтобы начать чтение, в статический метод Create передается объект класса XmlReaderSettings. Эта функция подсчитывает число узлов в документе.

using System.Xml; using System.IO; private int CountNodes(string xmlFile) { int NodesCount=0; XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreWhitespace = true; settings.IgnoreComments = true; using (XmlReader reader = XmlReader.Create(xmlFile, settings)) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { NodesCount++; } } } return NodesCount; }

Класс XmlReader позволяет извлекать из документа классы CLR. Пусть у нас есть меню ресторана.

Напишем функцию, которая посчитает сумму цен и количества калорий в меню.

protected void Page_Load(object sender, EventArgs e) { int ItemsCount = 0; decimal DishesTotal = 0; UInt16 CaloriesTotal = 0; XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreWhitespace = true; NameTable nt = new NameTable(); object food = nt.Add("food"); object price = nt.Add("price"); object calories = nt.Add("calories"); settings.NameTable = nt; string MenuFile = Path.Combine(Request.PhysicalApplicationPath, "menu.xml"); using (XmlReader reader = XmlReader.Create(MenuFile, settings)) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && food.Equals(reader.LocalName)) { ItemsCount++; } if (reader.NodeType == XmlNodeType.Element && price.Equals(reader.LocalName)) { DishesTotal += (UInt16)reader.ReadElementContentAsDecimal(); } if (reader.NodeType == XmlNodeType.Element && calories.Equals(reader.LocalName)) { CaloriesTotal += (UInt16)reader.ReadElementContentAsInt(); } } } Response.Write(String.Format("Вы заказали {0} блюда на сумму {1:C}, {2} калорий", ItemsCount, DishesTotal, CaloriesTotal)); }

Класс XPathDocument

Класс обеспечивает чтение и хранение в памяти XML-документов для трансформаций с помощью XSL. По документу можно перемещаться в любом направлении и получать произвольный доступ к любому элементу, используя выражения XPath.

Возьмем XML-документ "Quotes.xml"и файл трансформации XSL "Quotes.xsl". В выходной поток страницы будет направлен результат преобразования XML-документа.

<% XPathDocument doc = new XPathDocument(Server.MapPath("App_Data\\Quotes.xml")); XslCompiledTransform xsl = new XslCompiledTransform(); xsl.Load(Server.MapPath("App_Data\\Quotes.xsl")); xsl.Transform(doc, null, Response.OutputStream); %>

Благодаря тому, что в файле трансформации определены табличные теги, на странице появится таблица с нужной информацией.

Элемент управления XML

Элемент управления XML предоставляет способ преобразовать XML-документ, используя таблицу стилей XSL. Свойство DocumentSource позволяют задать XML-файл, в котором находятся данные, TransformSource - файл трансформации XSLT.

В предыдущем примере того же результата можно достичь, если поставить на странице элемент управления XML.

XMLDataSource

Элемент -источник данных XMLDataSource обеспечивает простой способ подключения XML-документов как источников данных к элементам, отображающим информацию. Также можно задать запрос XPath для того, чтобы отфильтровать данные. Как и SqlDataSource, он позволяет редактировать, удалять, добавлять записи данных. Для этого нужно получить доступ к находящемуся в нем объекту XmlDataDocument с помощью вызова метода GetXmlDocument. После редактирования документ сохраняется с помощью метода Save.

В отличие от табличных данных в СУБД, данные в XML-файлах иерархичны, поэтому XMLDataSource удобно привязывать к иерархичным элементам управления, например Menu.

Синтаксис привязки к данным XML

Так как в приложениях XML-данные используются все чаще и чаще, был введен метод привязки данных, полученных из XMLDataSource.

Эти методы работают так же, как Bind и Eval, которые обсуждались в 7 лекции.

Применим этот синтаксис в элементе DataList, который получает данные из источника данных XmlDataSource:

Заключение

В этой лекции мы рассмотрели работу с данными типа XML. XML предоставляет универсальный способ для описания и обмена структурированной информацией, независимо от приложений и разработчиков. На этом завершили рассмотрение работы с источниками данных.

Цель работы: получить практические навыки обработки данных, представленных в формате Extensible Markup Language (XML ).

Задачи работы:

– изучить технологию описания данных XML ;

– изучить основные классы библиотеки FCL , поддерживающие обработку данных, представленных в формате XM L;

– выполнить практическое задание по разработке приложения на языке С#.

Краткие теоретические сведения

Формат XML – это способ хранения данных, представленных в простом текстовом формате, что означает, что эти данные могут быть прочитаны практически любым компьютером. Данное обстоятельство делает этот формат весьма подходящим для использования при передаче данных через Интернет и допускает даже непосредственное прочтение человеком.

XML является языком разметки, с помощью которого можно описать произвольные данные. На основеэтогоязыка можно организовать хранение информации и ее обмен, не зависящий ни от конкретных приложений, ни от платформы, на которой они исполняются.

XML - документы. Законченный набор данных известен в языке XML под названием XML -документа. XML -документ может представлять собой физический файл на вашем компьютере, а может быть всего лишь строкой в памяти, однако он должен быть законченным и подчиняться определенным правилам. XML -документ состоит из нескольких различных частей, наиболее важными из которых являются XML- элементы, где содержатся те данные, из которых собственно и состоит документ.

Microsoft . NET Framework использует объектную модель данных XML Document Object Model(DOM ), чтобы обеспечить доступ к данным в XML -документах, и дополнительные классы для чтения, записи и навигации в пределах XML -документа. Эти классы поддерживаются пространством имен System.XML . Пример представления описания каталога книг в модели DOM приведен на рис. 8.1.

Описание документа на языке XML включает в себя операторы, написанные с соблюдением требований его синтаксиса. При создании XML -документа вместо использования ограниченного набора определенных элементов имеется возможность создавать собственные элементы и присваивать им любые имена по выбору пользователя. Именно поэтому язык XML является расширяемым (extensible). Следовательно, этот язык можно использовать для описания практически любого документа: от музыкальной партитуры до базы данных.

Katalog

Рис. 8.1. Иерархическая структура документа

Например, каталог книг можно описать так, как показано в листинге 8.1 (номера строк не являются частью документа XML ). Для создания XML -документа в среде Visual Studio . NET следует воспользоваться командой File \ New File и в выпавшем списке шаблонов выбрать имя шаблона XML File .

Листинг 8.1 . Текст XML -документа

    С#2005 для профессионалов

    Кристиан Нейгел

    1560

    800

    2006

    С# в задачах и примерах

    Никита Культин

    240

    350

    2007

В строке 1 данного листинга записано объявление XML , идентифицирующее текст как документ XML .Несмотря на необязательность объявления XML , документ должен включать его в себя для идентификации используемой версии XML , поскольку документ без объявления XML может в дальнейшем рассматриваться как соответствующий последней версии XML, в результате чего могут появиться ошибки. Информационный параметр version указывает версию XML , использованную в документе, параметр encoding – кодировку документа (utf-8 ).

В строке2 записан комментарий, начинающийся с символов . Комментарии можно размещать по всему XML -документу.

В XML -документе данные маркируются с помощью тэгов (элементов ), представляющих собой имена, заключенные в угловые скобки (< > ). Имена тэгов в XML -документе (такие как KATALOG , BOOK , TITLE , AUTHOR ,PAGES ,PRICE , PDATA в листинге 8.1) не являются определениями языка XMLи назначаются при создании документа. Для тэгов можно выбирать любые корректно заданные имена, например INVENTORY вместо KATALOG либо ITEM вместо BOOK . В строке 3 записан корневой тэг – KATALOG , открывающий разметку всего документа. При завершении написания корневого тэга среда автоматически вставляет конечный тэг (строка 18 листинга 8.1), отмечая его символами .

Примечание . Попытка создания более одного корневого элемента в XML -документе является ошибкой.

Внутри корневого элемента может находиться произвольное количество вложенных элементов. В листинге 8.1 XML -документ имеет иерархическую структуру в виде дерева с элементами, вложенными в другие элементы, и с одним элементом верхнего уровня элемент Документ , или Корневой элемент (в нашем примере – KATALOG ), который содержит все другие элементы. Корневой элемент KATALOG включает в себя элементы-потомки BOOK . В свою очередь элемент BOOK состоит из элементов-потомков TITLE , AUTHOR ,PAGES ,PRICE , PDATA .

Корректно сформированные XML-документы. Документ называется корректно сформированным (well-formed), если он соответствует следующему минимальному набору правил для XML -доку-ментов:

XML -документ должен иметь только один корневой элемент – элемент Документ . Все другие элементы должны быть вложены в корневой элемент;

– элементы должны быть вложены упорядоченным образом. Если элемент начинается внутри другого элемента, то он должен и заканчиваться внутри этого элемента;

– каждый элемент должен иметь начальный и конечный тэги. В отличие от языка HTML, в языке XML не разрешается опускать конечный тэг даже в том случае, когда браузер в состоянии определить, где заканчивается элемент;

– название элемента в начальном тэге должно точно соответствовать (с учетом регистра) названию в соответствующем конечном тэге;

– название элемента должно начинаться с буквы или с символа подчеркивания (_ ), после чего могут идти буквы, цифры, а также символы: точка (. ), тире (- ) или подчеркивание.

Это базовые правила корректного формирования XML -документа. Для других понятий языка XML (атрибутов, примитивов, связей) действуют свои правила, которые необходимо соблюдать. Можно сказать, что если документ создан правильно и при его отображении и использовании не возникает никаких ошибок, то это и есть корректно сформированный документ. Если вы ошибетесь в каком-либо тэге HTML -страницы, то браузер просто проигнорирует соответствующий тэг, а ошибка в тэге XML -страницы сделает невозможным ее отображение. При наличии одной из ошибок встроенный в Internet Explorer анализатор (его иногда называют XML -про-цессором, или парсером) определяет ее позицию

Классы библиотеки FCL для чтения XML-файлов. Работу с XML -документами поддерживают следующие классы библиотеки FCL : XmlTextReader , XmlDocument , XPathNavigator .

Класс XmlTextReader – это абстрактный класс, выполняющий чтение и обеспечивающий быструю доставку некэшированных данных.Этот подход в отношении серверных ресурсов является наименее дорогостоящим, но он принуждает извлекать данные последовательно, от начала до конца.

КлассXmlDocument представляет собой реализацию модели DOM . Этот класс удерживает данные в памяти после вызова метода Load () для извлечения их из файла или потока, обеспечивает древовидное представление документа в памяти с возможностями навигации и редактирования, а также позволяет модифицировать данные и сохранять их обратно в файл.

КлассXPathNavigator так же, как и класс XmlDocument , удерживает в памяти XML - документ целиком. Он предоставляет расширенные средства поиска данных, однако не обеспечивает возможности внесения изменений и их сохранения.

Класс XmlTextReader . Рассмотрим простой пример. Разместим на форме элементы richTextBox и button (рис. 8.2). При щелчке на кнопку в элемент richTextBox будет загружаться файл, содержимое которого было представлено в листинге 8.1. Код функции, вызываемой при щелчке на кнопку, показан в листинге 8.2.

Рис. 8.2. Результаты считывания из Xml -документа

Листинг 8.2 . Код обработчика щелчка по кнопке

//Очистка элемента richTextBox 1

richTextBox 1. Clear ();

// Вызов статического метода Create () , возвращающего объект класса

// Файл book.xml находится в том же месте, что и исполняемый файл

// программы

// Метод Read () перемещает на следующий узел Xml -документа

while (rdr.Read())

if (rdr.NodeType == XmlNodeType .Text)

richTextBox1.AppendText(rdr.Value + "\r\n");

Класс XmlReader также может читать данные со строгим контролем типов. Существует несколько методов ReadElementContentAs , выполняющих чтение, среди которых ReadElementContentAsDecimal() ,ReadElementContentAs Int () , ReadElementContentAs Boolean () и др.

В листинге 8.3 показано, как считывать значения в десятичном формате и выполнять над ними математические операции. В рассматриваемом случае цена элемента увеличивается на 25 %. Результаты выполнения этого кода показаны на рис. 8.3.

Рис. 8.3. Результаты считывания из Xml- документа

только названия и цены книг

Листинг 8.3 . Чтение данных со строгим контролем типов

// Очистка элемента richTextBox 1

richTextBox 1. Clear ();

// Создание потока для чтения из файла book . xml

XmlReader rdr = XmlReader.Create("book.xml");

while (rdr.Read())

if (rdr.NodeType == XmlNodeType.Element)

// Проверка имени элемента

if (rdr . Name == " PRICE ")

// Метод ReadElementContentAsDecimal () выполняет

// преобразование содержимого элемента к типу decimal

decimal price = rdr.ReadElementContentAsDecimal();

richTextBox1.AppendText(" Текущая цена = " + price +

"руб\ r \ n ");

// Изменение цены на 25 %

price += price * (decimal).25;

richTextBox1.AppendText(" Новая цена = " + price +

" руб \r\n\r\n");

else if (rdr.Name == "TITLE")

richTextBox1.AppendText(rdr.ReadElementContentAsString() + "\r\n");

Класс XmlDocument. Этот класс и производный от него класс XmlDataDocument используются в библиотеке .NET для представления объектной модели документа DOM .

В отличие от класса XmlReader , класс XmlDocument предла-гает возможности не только чтения, но и записи, а также произвольного доступа к дереву DOM .

Рассмотрим пример, в котором создается объект класса XmlDocument , загружается документ с диска и отображается окно списка с названиями книг (рис. 8.4).

Рис. 8.4. Отображение названий книг в списке.

В классе формы приложения создадим объект класса XmlDocument :

XmlDocument _doc = new XmlDocument();

Код обработчика щелчка по кнопке приведен в листинге 8.4.

_doc.Load("book.xml");

// Получить только те узлы, которые нужны

XmlNodeList nodeLst = _ doc . GetElementsByTagName (" TITLE ");

// Просмотр в цикле класса XmlNodeList

foreach (XmlNode node in nodeLst )

listBox 1. Items . Add (node . InnerText );

Введем в приложение возможность вывода свдений о книге, наз-вание которой выделено в списке, для чего добавим обработчик события listBox 1_ SelectedIndexChanged так, как показано в листинге 8.5.

Листинг 8.5 . Обработчик щелчка по элементу списка

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)

// Создание строки поиска

string srch = "KATALOG/BOOK";

// Поиск дополнительных данных

XmlNode foundNode = _doc.SelectSingleNode(srch);

if (foundNode != null)

MessageBox.Show(foundNode.OuterXml);

MessageBox.Show("Not found");

Результаты работы приложения показаны на рис. 8.5.

Рис. 8.5. Вывод сведений о выделенном элементе списка

С помощью класса XmlDocument такжеможно вставлять узлы в существующий документ, для чего используется метод Create - Element () .

Например, для создания нового элемента BOOK необходимо записать следующий код:

XmlElement newBook = _doc.CreateElement("BOOK");

Создать элементы, вложенные в элемент BOOK , можно с помощью следующего кода:

// Создание нового элемента AUTOR

XmlElement newAuthor = _doc.CreateElement("AUTOR");

newAuthor.InnerText = "C. Байдачный ";

Полный код обработчика щелчка по кнопке приведен в лис-тинге 8.6, результаты его работы показаны на рис. 8.6.

Листинг 8.6 . Обработчик щелчка по кнопке

private void button 1_ Click (object sender , EventArgs e )

_doc.Load("book.xml");

XmlElement newBook = _doc.CreateElement("BOOK");

// Создание нового элемента TITLE

XmlElement newTitle = _doc.CreateElement("TITLE");

newTitle.InnerText = ".NET Framework 2.0";

newBook.AppendChild(newTitle);

// Создание нового элемента AUTOR

XmlElement newAuthor = _doc.CreateElement("AUTOR");

newAuthor.InnerText = "C. Байдачный ";

newBook.AppendChild(newAuthor);

// Создание нового элемента PAGES

XmlElement newpages = _doc.CreateElement("PAGES");

newpages.InnerText = "498";

newBook.AppendChild(newpages);

// Создание нового элемента PRICE

XmlElement newprice = _doc.CreateElement("PRICE");

newprice.InnerText = "590";

newBook.AppendChild(newprice);

// Создание нового элемента PDATA

XmlElement newpdata = _doc.CreateElement("PDATA");

newpdata.InnerText = "2006";

newBook.AppendChild(newpdata);

// Добавление в текущий документ

_doc.DocumentElement.AppendChild(newBook);

// Запись документа на диск

XmlTextWriter tr = new XmlTextWriter("bookEdit.xml", null);

tr.Formatting = Formatting.Indented;

_doc.WriteContentTo(tr);

tr . Close ();

XmlNodeList nodeLst = _ doc . GetElementsByTagName (" TITLE ");

// Просмотр в цикле класса XmlNodeList

foreach (XmlNode node in nodeLst )

listBox 1. Items . Add (node . InnerText );

При использовании классовXmlDocument иXmlReader необходимо учитывать следующие особенности. Если требуется возможность произвольного доступа к документу, то следует применять класс XmlDocument , а если нужна потоковая модель, то классы, основанные на классе XmlReader . Класс XmlDocument отличается большой гибкостью, но его требования к памяти являются более высокими, чем у классаXmlReader , а производительность при считывании документа – более низкой.

Рис. 8.6. Окно работающего приложения

с добавленным узлом

Класс XPathNavigator . КлассXPathNavigator является частью пространства имен System . Xml . XPath , созданного для увеличения быстродействия. Это пространство обеспечивает только чтение документов, следовательно средства редактирования в нем отсутствуют, а классы построены так, чтобы обеспечить быстрое выполнение на заданном XML -документе циклов и операций выбора в стиле курсора.

Наилучшим способом использования классов из пространства имен System . Xml . XPath является просмотр документа book . xml в цикле.

Разместим на форме элементы listBox и button . Код обра-ботчика щелчка по кнопке приведен в листинге 8.7, результаты выполнения этого кода – на рис. 8.7.

Листинг 8.7 . Обработчик щелчка по кнопке

private void button 1_ Click (object sender , EventArgs e )

// Создание объекта с именем doc класса XPathDocument и передача

// в его конструктор имени XML - файла book.xml

XPathDocument doc = new XPathDocument("book.xml");

// Создание объекта с именем nav класса XPathNavigator на базе объекта

// XPathDocument. Объект nav может использоваться только для чтения

XPathNavigator nav = ((IXPathNavigable)doc). CreateNavigator();

// Создание объекта XPathNodeIterator для узлов каталога

// и его дочерних узлов

XPathNodeIterator iter = nav.Select("/KATALOG/BOOK");

while (iter.MoveNext())

// Метод SelectDescendants() класса XPathNavigator выбирает все

// узлы-потомки текущего узла, соответствующие условиям выбора

XPathNodeIterator newIter =