Меню
Бесплатно
Главная  /  Работа в Интернете  /  Работа с XML в.NET-приложениях. Как открыть XML-документ – особенности работы с XML-файлами Создание XML элемента с дочерними элементами

Работа с XML в.NET-приложениях. Как открыть XML-документ – особенности работы с XML-файлами Создание XML элемента с дочерними элементами

Extensible Markup Language (XML). Это действительно просто текстовые файлы, которые используют пользовательские теги для описания структуры и других функций документа.

Что такое XML

XML – это язык разметки, созданный консорциумом World Wide Web Consortium (W3C) для определения синтаксиса кодирования документов, которые могут быть прочитаны людьми и машинами. Он делает это с помощью тегов, которые определяют структуру документа, а также то, как документ должен храниться и транспортироваться.

Проще всего сравнить его с другим языком разметки, с которым вы можете быть знакомы, – язык гипертекстовой разметки (HTML), используемый для кодирования веб-страниц. HTML использует предопределенный набор символов разметки (короткие коды), которые описывают формат содержимого на веб-странице.

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

По сути, HTML – это язык, который фокусируется на представлении контента, в то время как XML – это выделенный язык описания данных, используемый для хранения данных.

XML часто используется в качестве основы для других форматов документов, которых сотни. Вот несколько, которые вы можете узнать:

  • RSS и ATOM описывают, как приложения должны обрабатывать веб-каналы.
  • Microsoft .NET использует XML для своих файлов конфигурации.
  • Microsoft Office использует XML в качестве основы для структуры документа.

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

Как открыть XML-файл

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

Используйте текстовый редактор при регулярной работе с XML

Поскольку XML-файлы – это просто текстовые файлы, их можно открыть в любом текстовом редакторе. Однако, многие текстовые редакторы, такие как Notepad, просто не предназначены для отображения XML-файлов с их правильной структурой. Это может быть полезно для быстро ознакомления с содержанием XML-файла. Но, существуют более удобные инструменты для работы с ними.


Использование веб-браузера для просмотра XML-файла

Если Вам не нужно редактировать XML-файл, но просто нужно просмотреть содержимое, с этой задачей справиться ваш браузер. Более того, ваш веб-браузер, скорее всего, уже настроен как стандартное средство просмотра XML-файлов. Таким образом, двойной щелчок XML-файла должен открыть его в браузере.

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

Когда файл откроется, вы должны увидеть хорошо структурированные данные. Это не так красиво, как цветной вид, который вы получаете в Notepad++, но гораздо лучше, чем блокнот.

Использование онлайн-редактора для XML-файлов

Если вы хотите редактировать случайный XML-файл и не хотите загружать новый текстовый редактор, или Вам нужно конвертировать XML-файл в другой формат , существует несколько достойных онлайн-редакторов XML, доступных бесплатно.

TutorialsPoint.com , XMLGrid.net и CodeBeautify.org – позволяют просматривать и редактировать XML-файлы. После завершения редактирования можно загрузить измененный XML-файл или даже преобразовать его в другой формат.

Для примера используем CodeBeautify.org. Страница разделена на три раздела. Слева находится XML-файл, с которым вы работаете. В середине вы найдете несколько функций. Справа вы увидите результаты некоторых вариантов, которые вы можете выбрать.

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

Используйте кнопку Browse для загрузки XML-файла с вашего компьютера или кнопку Load URL для извлечения XML из интернет-источника

Кнопка Tree View отображает данные в хорошо отформатированной древовидной структуре на панели результатов, со всеми тегами, выделенными оранжевым цветом, и атрибутами справа от тегов.

Beatify отображает ваши данные в аккуратном, легко читаемом виде.

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

И, наконец, Вы можете использовать кнопку XML to JSON для преобразования XML в формат JSON, и кнопку Export to CSV для сохранения данных в виде файла значений, разделенных запятыми, или кнопку Download для загрузки любых изменений, которые вы сделали в новом 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 =

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


Зачем нам работать с XML?

Если вы ещё не очень хорошо представляете себе, что такое XML, то рекомендую прочитать статью "XML - это всерьёз и надолго" в "КВ" № за 2007-й год. Чтобы сэкономить место для более важных вещей, здесь сам формат XML разбираться не будет.

Перед тем, как начинать знакомиться с программным кодом, нужно ответить на один принципиальный вопрос: зачем вообще включать поддержку XML в своё приложение? Думаю, что многие задавали себе этот вопрос относительно многих технологий, и не все после ответа были включены в приложения. Впрочем, с XML дело обстоит несколько иначе, и существуют реальные поводы использовать этот формат во многих ситуациях.

Главное преимущество XML в том, что, будучи по природе текстовым форматом, он, тем не менее, прекрасно позволяет хранить и передавать любые данные. Поскольку этот формат текстовый, то сама собой решается проблема его кросс-платформенности, и точно так же легко решается проблема передачи XML-данных (как это, например, сделано в SOAP). Кроме того, можно без проблем изменять формат передачи или хранения данных, добавляя новые атрибуты и не сильно беспокоясь о совместимости с предыдущими версиями формата, поскольку приложения, использующие старую версию, смогут прочитать то, что им надо, не обращая внимания на новые теги или атрибуты. Многие приложения используют основанные на XML файловые форматы, многие протоколы передачи данных тоже основаны на XML, и списки тех и других продолжают расти.

Конечно, с другой стороны, XML не очень экономичен, потому что, как когда-то верно заметил один из посетителей форума "Компьютерных вестей", часто XML-документы состоят на 10% из данных и на 90% из тегов. Впрочем, это уже в значительной степени зависит от того, какие вы сами выберете теги. Можно написать ул. Мельникайте, 2, а можно . Хотя, если честно, мне кажется, что с нынешними винчестерами и толстыми каналами нет смысла особенно ужиматься.

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

Для программирования мы будем использовать основной язык платформы.NET - C#. Для того, чтобы как можно больше читателей могли сами поупражняться с приведенным программным кодом, я буду использовать первую версию C# и.NET Framework"а.


Запись данных

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

Для начала создайте новый проект в Visual Studio, #Develop"е или C# Builder"е, и в список импортируемых namespace"ов добавьте System.Xml.

За запись XML-данных в.NET Framework"е отвечает специальный класс XmlTextWriter, который позволяет записывать XML-данные в произвольный поток. То есть, мы, вообще говоря, можем записать их с его помощью и в файл, и в базу данных, и отправить кому-то через Интернет, однако сейчас мы будем писать всё именно в файл. Вы можете перенаправить вывод, изменив конструктор объекта (т.е. передав при инициализации не имя файла и его кодировку, а объект, являющийся потоком данных). Впрочем, я, кажется, уже стал забегать немного вперёд. Давайте сначала познакомимся с кодом, ответственным за запись данных в наш с вами XML-файл.

String FileName = "c:\\demo.xml"; XmlTextWriter xml = new XmlTextWriter(FileName, System.Text.Encoding.Unicode); xml.Formatting = Formatting.Indented; xml.WriteStartDocument(); xml.WriteStartElement("rootelement"); for (int i = 0; i < 10; i++) { xml.WriteStartElement("subelement"); xml.WriteAttributeString("attrib1", "value1"); xml.WriteAttributeString("attrib2", i.ToString()); for (int j = 0; j < 10; j++){ xml.WriteStartElement("subsubelement"); xml.WriteAttributeString("attr", j.ToString()); xml.WriteEndElement(); } xml.WriteEndElement(); } xml.WriteEndElement(); xml.WriteEndDocument(); xml.Close();

Первая строка, думаю, вполне ясна - это просто запись имени файла, в который мы будем сохранять данные. Дальше мы создаём объект типа XmlTextWriter (он называется, как видите, xml), и именно с ним мы будем производить все дальнейшие операции. Заметьте, что при конструировании объекта мы указываем и кодировку, в которой будет записываться XML: в нашем примере это Unicode. Следующая строчка, вообще говоря, не обязательна, однако она сделает наш XML-документ, что называется, human readable, то есть добавит нужные отступы и разобьёт его на строки. Без этого весь документ был бы записан одной строкой, что, хотя и экономит место, но делает его практически непригодным для ручного редактирования.

Начинается запись документа с вызова метода WriteStartDocument() нашего объекта xml. Следующая за ней строчка добавляет корневой элемент "rootelement" в наш XML-документ (напомню, для XML-документов корневой элемент должен присутствовать в единственном экземпляре). Далее мы в цикле добавляем ещё десять не несущих никакой смысловой нагрузки элементов в наш с вами XML-документ, для каждого из которых устанавливаем два атрибута и ещё по десять подэлементов. Обратите внимание, что мы можем добавлять к строке число без явной конвертации данных, а вот если число должно целиком образовывать строку, то его нужно преобразовывать явно методом ToString(). Также обратите внимание, что мы должны явно закрывать каждый из элементов нашего XML-документа, а также потом и весь документ целиком.

Теперь, когда наш XML-документ успешно записан, давайте посмотрим, каким образом можно считать из него данные.


Чтение данных

Добавьте на форму вашего приложения (если, конечно, оно у вас не консольное) компонент listBox для того, чтобы можно было следить за результатом чтения XML-файла. Ну а если ваша программа консольная , то вы с лёгкостью сможете перенаправить вывод на консоль.

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

XmlTextReader xml = new XmlTextReader(FileName); xml.WhitespaceHandling = WhitespaceHandling.None; int i = 0; while (xml.Read()){ if ((xml.NodeType == XmlNodeType.Element) & (xml.Name == "subelement")) { listBox1.Items.Add("subelement " + i + " found"); i++; listBox1.Items.Add(" " + xml.GetAttribute("attrib1")); listBox1.Items.Add(" " + xml.GetAttribute("attrib2")); while (xml.Read()&(xml.Name == "subsubelement")){ listBox1.Items.Add(" " + xml.GetAttribute("attr")); } } } xml.Close();

Для чтения, как вы могли заметить, мы используем уже другой класс, а именно - XmlTextReader. Он находится в том же пространстве имён, что и класс, который мы использовали для записи данных. В первой строчке мы создаём экземпляр XmlTextReader"а, имеющий имя xml (здесь мы предполагаем, что переменная FileName уже определена нами ранее). Чтобы пропускать пустые строки, ежели такие неким непостижимым образом возникнут в нашем только что созданном XML-файле, мы используем следующую строку в приведенном фрагменте кода. Переменная i используется для подсчёта количества найденных элементов "subelement" в XML-файле, из которого производится считывание данных.

Дальше идёт цикл непосредственного чтения данных из файла. Метод Read() считывает следующий элемент XML-документа, и после его считывания мы проверяем, что именно мы считали. Если это действительно элемент "subelement", то мы добавляем информацию о считанном элементе в listBox1, инкрементируем переменную, содержащую количество считанных элементов, а затем считываем атрибуты элемента. После чтения атрибутов мы организуем отдельный цикл для чтения подэлементов "subsubelement" (обратите внимание, что для этого нам не требуется отдельного XmlTextReader"а) и атрибутов этих подэлементов. Как и ранее, все считанные сведения мы заносим в listBox1, чтобы контролировать правильность чтения.

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


За кадром

В общем-то, пример, который мы с вами только что разобрали, чересчур прост для реальных проектов. В наше время при чтении XML-документов, как правило, применяется их валидация с помощью DTD, XML Schema или Relax NG. Валидация - это проверка соответствия разметки XML-документа некоторому стандарту, описываемому во внешнем файле. Валидация нужна для того, чтобы проверка документа не была жёстко зашита в алгоритм программы, а могла изменяться произвольным образом при изменении в формате данных без обновления считывающего или записывающего данные программного кода. К сожалению, сейчас мы с вами уже разобрать валидацию не успеем, поскольку, как вы сами понимаете, объём газетной статьи имеет определённые ограничения.

Ещё один интересный и полезный практический момент, касающийся работы с XML-данными, - это XSL-преобразование данных. Это преобразование применяется к данным при их отображении на HTML-страницах и, фактически, просто является применением определённого шаблона web-страницы к XML-файлу с какими-либо данными. Поскольку львиная доля теперешнего использования XML-данных так или иначе приходится на World Wide Web, то и XSL-преобразования рассмотреть было бы очень и очень неплохо.

Так что, думаю, у этой статьи будет продолжение - но, конечно, только в том случае, если вы сами (то есть читатели "Компьютерных вестей") об этом попросите на форуме или в письме на мой электронный почтовый адрес. Пока же об использовании XML в.NET-приложениях, пожалуй, всё. Надеюсь, что эта информация будет полезной для вас.

Одним из наиболее важных усовершенствований Excel 2003 является возможность открывать, импортировать и экспортировать данные XML (extensible Markup Language - язык расширяемой разметки) любой структуры. Предыдущие версии Excel поддерживали XML в ограниченной степени: они позволяли сохранять и открывать электронные таблицы только определенной схемы XML, так называемой таблицы XML (XML Spreadsheet). Данные в файлах XML, основанных на других схемах, просто блокировались.

Открытие и импорт списка XML

Чтобы открыть список, сохраненный в файле XML, просто выберите команду Файл? Открыть. В раскрывающемся списке типов файлов диалогового окна Открытие документа выберите пункт Файлы XML (XML Files) или Все файлы Microsoft Office Excel (All Microsoft Excel Files) (последний тип устанавливается в Excel по умолчанию). После указания нужного вам файла и нажатия кнопки Открыть (Open) появится диалоговое окно Открытие XML (Open XML), показанное на рис. 29.6. При выборе первого варианта, XML-список (As An XML List), создается список, в котором каждый элемент структуры XML становится столбцом (рис. 29.7).

Рис. 29.6. Выберите первый вариант, чтобы открыть все элементы структуры XML как столбцы списка, или третий вариант, чтобы работать только с отдельными элементами

Как видно из рис. 29.7, результатом открытия файла XML как XML-списка является объект списка, в котором столбцы представляют элементы исходного файла с сохранением порядка следования. Все записи из исходного файла включаются в конечный список.

Команда Файл? Открыть создает новую книгу. Чтобы создать список XML в существующей книге, нужно использовать команду Данные? XML ? Импорт (Data ? XML ? Import).

Рис. 29.7. Каждому элементу открытого файла XML сопоставлен столбец конечной таблицы XML, которую Excel превращает в объект «список»

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

Например, в список на рис. 29.7 мы можем добавить вычисляемый столбец, чтобыполучить стоимость партии товара на основе цены единицы товара, количества и скидки (столбцы Цена, Количество и Скидка соответственно). Для этого мы должны ввести подходящий заголовок в ячейку F1 и формулу =C2*D2*(1-E2) в ячейку F2. Excel добавит столбец Е в список. На рис. 29.8 показан результат этих действий после автоматического распространения формулы из ячейки F2 на остальные ячейки столбца Е.

Обновление списка XML

Список XML обновляется по требованию. Чтобы обновить его текущими данными из исходного файла XML, просто нажмите кнопку Обновить XML-данные (Refresh XML Data) на панели инструментов Список (List) или выберите команду

Данные? XML ? Обновить XML-данные (Data ? XML ? Refresh XML Data). В отличие от других типов списков и запросов, список XML нельзя обновлять по расписанию.

Рис. 29.8. Вы можете работать со списком XML точно так же, как с любым объектом списка. В данном случае, создав заголовок нового столбца и написав единственную формулу, мы добавили в список вычисляемый столбец

Работа со столбцами в списке XML

При работе со столбцами в списке XML в вашем распоряжении все способы, описанные в главе 28 (см. раздел «Вставка и удаление строк и столбцов»). Так, чтобы удалить столбец, следует выделить его и выбрать команду Удалить столбец (Delete Column) в меню Правка (Edit). Если мы хотим поместить столбец Скидка между столбцами Цена и Количество, это будет выглядеть как выделение столбца Скидка и перетаскивание его мышью на позицию слева от столбца Количество.

Если вы хотите работать только с определенными столбцами структуры XML или отображать столбцы в другом порядке, а не по умолчанию, в большинстве случаев удобнее открывать список, выбрав третий вариант в диалоговом окне Открытие XML, который мы рассмотрим в следующем разделе.

Сопоставление элементов XML и столбцов списка

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

скорее всего, вас будет интересовать только некоторая часть составляющих его данных. В таких случаях рекомендуется третий вариант открытия, а именно Использовать область задач XML-источника (Use The XML Source Task Pane). Тогда Excel ищет файл схемы, связанный с открываемым файлом. Если такая схема найдена, файл с данными открывается в режиме конструктора XML, где элементы его структуры представлены в соответствии со схемой, отображаемой на панели задач Источник XML, аналогично рис.

29.9. Если файл данных не требует схемы, но Excel в состоянии предложить свою схему,

основываясь на структуре данных, вы увидите следующее информационное окно.

Щелкните на кнопке ОК. Список откроется в режиме конструктора, и структура файла отобразится в панели задач Источник XML.

Обновить XML-данные Импорт XML-данных

Рис. 29.9. Если вы открываете файл XML с целью сопоставления элементов и столбцов списка, Excel открывает список в режиме конструктора. Данные отобразятся на листе только после того, как вы перетащите элементы XML из панели задач на лист и обновите список или выполните импорт

В примере, продемонстрированном на рис. 29.9, исходный файл содержит информацию об ассортименте предлагаемых книг. Чтобы создать объект списка на рабочем листе, отображающий эти поля, нужно выделить (при нажатой клавише Ctrl) представляющие интерес заголовки и затем перетащить их на лист. (В Excel процесс связывания элементов XML с заголовками списка называется отображением (mapping).) Результат показан на рис. 29.10.

Рис. 29.10. Перетащите заголовки из панели задач Источник XML, чтобы создать список,

отображающий только определенные столбцы (здесь сопоставлены все элементы XML)

Для того чтобы заполнить созданный список, используйте команду Данные? XML ? Обновить XML-данные (Data ? XML ? Refresh XML Data) или Данные? XML ? Импорт (Data ? XML ?Import). Команда Обновить XML-данные переносит данные в список из файла, структура которого отражена на панели задач Источник XML. Команда Импорт позволяет получать записи из любого файла, имеющего точно такую же структуру, и поэтому она запрашивает его имя. Импортирование особенно полезно, когда у вас имеется ряд одинаково структурированных файлов XML.

СОВЕТ

Если вы последовательно импортируете несколько файлов с идентичной структурой, каждый следующий результат заменяет предыдущий. При необходимости импортировать сразу несколько файлов выберите команду Данные? XML ? Импорт. Затем в диалоговом окне Импорт XML (Import XML) выделите при нажатой клавише Ctrl имена всех интересующих вас файлов.

Ниже приведено несколько дополнительных замечаний относительно импорта файлов

Книга Excel может содержать несколько импортированных схем или структур. Чтобы импортировать следующую схему или добавить структуру, выберите команду Данные

XML ? Импорт или отобразите панель задач Источник XML, нажмите кнопку

Карты XML (Worbook Maps) и затем кнопку Добавить (Add).

Элементы одной структуры допускается сопоставлять с несколькими списками, но каждый элемент может быть связан только с одним списком.

Элементы из одной схемы разрешено отображать на несколько рабочих листов одной книги, но только не в разные книги.

Экспорт списка XML

Чтобы экспортировать содержимое текущего списка XML как правильно организованного файла XML, выберите команду Данные? XML ? Экспорт (Data ? XML ? Export) и укажите имя файла. Обратите внимание: если файл уже существует, ваши данные заменят текущее содержимое этого файла. Команда Экспорт полезна, когда вы хотите сделать Excel средством для редактирования имеющегося файла XML или для добавления в него новых данных. Вы также вправе использовать ее для создания новых файлов в соответствии с существующей схемой или структурой, построенной на основе самих данных.

ПРИМЕЧАНИЕ

Команда Экспорт не подключает правила проверки данных, предусмотренные схемой. Подсистема экспорта обнаруживает ошибочные данные и сообщает о них, но, несмотря на это, экспортирует их в файл.

В предыдущей статье были описаны общие понятия касающиеся 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");