17323

Создание XML-документов в .NET

Лекция

Информатика, кибернетика и программирование

Лекция 9. Создание XMLдокументов в .NET План 1. Использование класса XmlWriter запись потоков данных Xml 2. Использование DOM в .Net 2.1. Чтение XMLдокумента с помощью XmlNodeList 2.2. Вставка элементов узлов в XML документ 3. Обработка атрибутов 3.1. Извлечение атрибутов с помощью XmlRead...

Украинкский

2013-06-30

123.45 KB

12 чел.

Лекция 9. Создание XML-документов в .NET

План

1. Использование класса XmlWriter - запись потоков данных Xml

2. Использование DOM в .Net

2.1. Чтение XML-документа с помощью XmlNodeList

2.2. Вставка элементов (узлов)  в XML- документ

3. Обработка атрибутов

3.1. Извлечение атрибутов с помощью XmlReader

3.2. Вставка атрибутов  в документ с помощью XmlWriter

1. Использование класса XmlWriter - запись потоков данных Xml

Таблица 1. Основные классы чтения и записи данных XML

XmlReader

Абстрактный класс, выполняющий чтение и обеспечивающий быструю доставку некешированных данных XML. Класс представляет собой однонаправленный синтаксический анализатор

XmlWriter

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

XmlTextReader

Реализация  класса XmlReader. Обеспечивает однонаправленный потоковый доступ к данным XML

XmlTextWtiter

Реализация  класса Xml.Writer. Обеспечивает быструю однонаправленную генерацию потоков XML

Для работы с данными каждый из классов предоставляет необходимые методы.

Класс XmlWriter позволяет записывать Xml-код в поток данных, файл, в класс StringBuilder, TextWriter  и другие объекты XmlWriter.

Класс легко конфигурируется, что позволяет определить потребность во вспомогательных установках, таких как отступы, кавычки, пространства имен и другое. Такое конфигурирование выполняется с использованием объекта XmlWriterSettings.

Создадим обработчик кнопки WriteXml  примера предыдущей лекции.

При нажатии кнопки WriteXml выполняется создание элементов XML-документа и запись его в новый файл  "booknew.xml");

      private void btmWriteXml_Click(object sender, EventArgs e)

       {

          // запись в файл

           XmlWriterSettings setting = new XmlWriterSettings();

           setting.Indent = true;

           XmlWriter writer = XmlWriter.Create("booknew.xml", setting);

           writer.WriteStartDocument();

           //начало создания єлементов

           writer.WriteStartElement("Catalog");

           writer.WriteStartElement("book");

           writer.WriteElementString("title", "Основы инженерии качества программных систем");

           writer.WriteStartElement("author");

           writer.WriteElementString("name", "Коротун Т.М.");

           writer.WriteElementString("name", "Коваль Г.И.");

           writer.WriteEndElement();

           writer.WriteElementString("price", "120.00");

           writer.WriteEndElement();

           writer.WriteEndElement();

           writer.WriteEndDocument();

           //Очистка потока

           writer.Flush();

           writer.Close();

       }

В этом примере создается новый XML-файл booknew.xml, в который записываются данные о новой книге. Класс XmlWriter перезаписывает существующее содержимое файла новым содержимым.  Для вставки новых элементов используются методы класса XmlWriter.  Для создания объекта XmlWriter используется статический метод Create(). В примере строка, представляющая имя файла, передается как параметр вместе с экземпляром класса XmlWriterSettings.

Класс XmlWriterSettings имеет свойства, управляющие способом создания Xml-докуметов. Например, свойство Indent – булевское значение, которое определяет, должны ли элементы выводиться с отступом.  Свойство IndentChars содержит  строку символов, используемую для отступа.  По умолчанию это строка из двух символов. Свойство NewLine служит для определения символа новой строки.  

Основные методы класса XmlWriter

WriteStartDocument()

добавляет объявление документа. После этого можно добавлять данные.

WriteEndDocument()

определяет конец документа (вставляет тег конца)

WriteStartElement()

добавляет новый элемент

WriteElementString

вставляет строку, указывающую имя и содержимое элемента

WriteEndElement

определяет конец элемента (вставляет тег конца)

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

В результате в папке приложения будет создан такой файл:

<?xml version="1.0" encoding="utf-8"?>

<Catalog>

 <book>

   <title>Основы инженерии качества программных систем</title>

   <author>

     <name>Коротун Т.М.</name>

     <name>Коваль Г.И.</name>

   </author>

   <price>120.00</price>

 </book>

</Catalog>

Этот файл содержит XML-документ, описывающий одну книгу.  Такой метод подходит для создания новых документов. А что делать, если необходимо добавить элемент в существующий XML-документ? Например добавить новую книгу в каталог. Для этого нужно воспользоваться классами  DOM.

2. Использование DOM в .Net

Реализация объектной модели документа (DOM, Document Object Model) в .NET поддерживает спецификации W3C DOM Level 1 и Core DOM Level 2. DOM реализуется с помощью класса XmlNode. XmlNode является абстрактным классом, который представляет узел документа XML. XmlNodeList является упорядоченным списком узлов. Это активный список узлов, и любые изменения в любом узле немедленно отражаются в списке. XmlNodeList поддерживает индексный доступ или итеративный доступ. Эти два класса составляют основу реализации DOM на платформе .NET.

Основные классы, которые основываются на XmlNode

Имя класса

Описание

XmlLinkedNode

Расширяет XmlNode. Возвращает узел непосредственно перед или после текущего узла. Добавляет свойства NextSibling и PreviousSibling в XmlNode.

XmlDocument

Расширяет XmlNode. Представляет весь документ. Реализует спецификации DOM Level 1 и Level 2.

XmlAttribute

Расширяет XmlNode. Объект атрибута объекта XmlElement.

XmlCDataSection

Расширяет XmlCharacterData. Объект, который представляет раздел документа CData.

XmlCharacterData

Абстрактный класс, который предоставляет методы манипуляции с текстом для других классов. Расширяет XmlLinkedNode.

XmlComment

Расширяет XmlCharacterData. Представляет объект комментария XML.

XmlDeclaration

Расширяет XmlLinkedNode. Представляет узел объявления (<?xml version='1.0' ...>)

XmlDocumentFragment

Расширяет XmlNode. Представляет фрагмент дерева документа.

XmlDocumentType

Расширяет XmlLinkedNode. Данные, связанные с объявлением типа документа.

XmlElement

Расширяет XmlLinkedNode. Объект элемента XML.

XmlEntity

Расширяет XmlNode. Синтаксически разобранный или неразобранный узел сущности.

XmlEntityReferenceNode

Расширяет XmlLinkedNode. Представляет ссылочный узел сущности

XmlNotation

Расширяет XmlNode. Содержит нотацию, объявленную в DTD или в схеме.

XmlProcessingInstruction

Расширяет XmlLinkedNode. Содержит инструкцию обработки XML.

XmlSignificantWhitespace

Расширяет XmlCharacterData. Представляет узел с разделителем. Узлы создаются, только если флаг PreserveWhiteSpace задан как true.

XmlWhitespace

Расширяет XmlCharacterData. Представляет разделитель в содержимом элемента. Узлы создаются, только если флаг PreserveWhiteSpace задан как true.

XmlText

Расширяет XmlCharacterData. Текстовое содержимое элемента или атрибута.

Как можно видеть .NET делает доступным класс, соответствующий почти любому типу XML. Диаграмма наследования классов.

2.1. Чтение XML-документа с помощью XmlNodeList

Создадим новое приложение WinXML-DOM WindowsApplication, которое будет читать данные книжного каталога и загружать названия книг в окно списка.

Для разнообразия данные будем выводить в Listbox. Это аналогично примеру применения XmlReader. Отличие заключается в том, что осуществляется выбор, с какими узлами мы хотим работать, вместо того чтобы использовать весь документ. Вот код для выполнения этого примера в среде XmlNode.

Добавим на форму список и две кнопки. Кроме того, добавим текстовые поля для следующей версии программы.

При нажатии кнопки Чтение в список выводим названия книг. Обработчик кнопки:

      private void btmReadXML_Click(object sender, EventArgs e)

       {

        // изменить путь доступа в соответствии со структурой путей доступа

         doc.Load("book2.xml");

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

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

         // итерации по списку XmlNodeList

        foreach(XmlNode node in nodeLst) listBox1.Items.Add(node.InnerText);

       }

Обратите внимание, что мы добавили следующее объявление на уровне модуля:

   public partial class Form1 : Form

   {      

       public XmlDocument doc = new XmlDocument();

        public Form1()

       {

           InitializeComponent();

       }

Если бы это было все, что нужно делать, то использование XmlReader было бы значительно более эффективным способом загрузки окна списка. Причина в том, что мы прошли через документ один раз и затем закончили с ним работу. Однако, если желательно повторно посетить узел, то использование XmlDocument является лучшим для этого способом.

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)

       {

           // создать строку поиска XPath

           string srch = "INVENTORY/BOOK[TITLE='" + listBox1.SelectedItem.ToString() + "']";

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

           XmlNode foundNode = doc.SelectSingleNode(srch);

           if (foundNode != null) MessageBox.Show(foundNode.InnerText);

           else MessageBox.Show("Not found");

       }

В этом примере listbox с заголовками загружается из документа book2.xml. Когда мы щелкаем на окне списка, вызывая порождение события SelectedIndexChange, мы берем текст выбранного пункта в listbox, в данном случае заголовок книги, создаем оператор XPath и передаем его в метод SelectSingleNode объекта doc. Он возвращает элемент book, частью которого является TITLE (foundNode). Выведем для наглядности InnerText узла в окне сообщения. Мы можем продолжать щелкать на элементах в listbox сколько угодно раз, так как документ загружен и остается загруженным, пока мы его не освободим.

Небольшой комментарий в отношении метода SelectSingleNode. Это реализация XPath в классе XmlDocument. Существуют методы SelectSingleNode и SelectNodes. Оба они определены в XmlNode, на котором основывается XmlDocument. SelectSingleNode возвращает XmlNode, и SelectNodes возвращает XmlNodeList.

2.2. Вставка элементов (узлов)  в XML- документ

Ранее рассматривался пример XmlTextWriter, который создает новый документ. Ограничение состояло в том, что он не вставлял узел в текущий документ. Это можно сделать с помощью класса XmlDocument.

Создадим в обработчике кнопки Запись код, Добавляющий в список и файл новую книгу (элемент BOOK).

private void btmSaveXML_Click(object sender, EventArgs e)

       {

           // изменить путь доступа, как требуется существующей структурой

           doc.Load("book2.xml");

           // создать новый элемент 'book'

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

           // создать новый элемент 'title'

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

           newTitle.InnerText = "Основы инженерии качества ПС";

           newBook.AppendChild(newTitle);

           // создать новый элемент author

           XmlElement newAuthor = doc.CreateElement("AUTHOR");

           newAuthor.InnerText = "Коротун Т.";

           newBook.AppendChild(newAuthor);

           XmlElement newName = doc.CreateElement("AUTHOR");

           newAuthor.InnerText = "Коваль Г.";

           newBook.AppendChild(newAuthor);

           // создать новый элемент Binding

        

           XmlElement newBind = doc.CreateElement("BINDING");

           newBind.InnerText = "Академпериодика";

           newBook.AppendChild(newBind);

           //

           XmlElement newPages = doc.CreateElement("PAGES");

           newPages.InnerText = "650";

           newBook.AppendChild(newPages);

           //

           XmlElement newPrice = doc.CreateElement("PRICE");

           newPrice.InnerText = "150";

           newBook.AppendChild(newPrice);

           

           // добавить к текущему документу

           doc.DocumentElement.AppendChild(newBook);

           // записать doc на диск

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

           tr.Formatting = Formatting.Indented;

           doc.WriteContentTo(tr);

           tr.Close();

           // загрузить listBox1 со всеми заголовками, включая новый

           listBox1.Items.Clear();

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

           foreach (XmlNode node in nodeLst)     listBox1.Items.Add(node.InnerText);

       }

При выполнении этого кода будет получена функциональность предыдущего примера, но в окне списка появилась одна дополнительная книга "Основы инженерии  качества ПС". Щелчок мыши на заголовке этой книги приведет к выводу такой же информации, как и для других книг.

В этом примере сначала создается новый элемент BOOK:

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

Метод CreateElement имеет три перегружаемые версии, которые позволяют определить имя элемента, имя и пространство имен URI, и, наконец, prefix (префикс), lоcalname (локальное имя) и namespace (пространство имен).

Потом добавляются новые элементы, вложенные в элемент BOOK.

           // создать новый элемент 'title'

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

           newTitle.InnerText = "Основы инженерии качества ПС";

           newBook.AppendChild(newTitle);

Здесь снова создается новый объект на основе XmlElement (newTitle). Присваиваем свойству InnerText заголовок новой книги и добавляем потомок к элементу book. Затем это повторяется для остальных элементов book.

Наконец, мы добавляем элемент newBook к узлу doc.DocumentElement. Это тот же уровень, что и у всех других элементов book. Мы заменили существующий документ новым, в отличие от XmlWriter, где можно было только создать новый документ. Последнее, что нужно сделать, это записать новый документ XML на диск. В этом примере мы создаем новый XmlTextWriter и передаем его в метод WriteContentTo. Не забудьте вызвать метод Close на XmlTextWriter, чтобы сбросить содержимое внутренних буферов и закрыть файл.

Методы WriteContentTo и WriteTo получают XmlTextWriter в качестве параметра. WriteContentTo сохраняет текущий узел и всех потомков в XmlTextWriter, в то время как WriteTo сохраняет текущий узел. Так как doc является объектом на основе XmlDocument, он представляет весь документ и поэтому будет сохранен. Можно было бы также использовать метод Save. Он всегда будет сохранять весь документ. Save имеет четыре перегружаемые версии. Можно определить строку с именем файла и путем доступа, объект на основе класса Stream, объект на основе класса TextWriter, или объект на основе XmlWriter. Именно это было использовано при выполнении примера. Добавим новый элемент в конец списка:

           listBox1.Items.Clear();

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

           foreach (XmlNode node in nodeLst) listBox1.Items.Add(node.InnerText);

В этом примере содержимое элементов формировалось просто в обработчике кнопки.

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

Обработчик кнопки Добавить:

      private void btmAdd_Click(object sender, EventArgs e)

       {

           // изменить путь доступа, как требуется существующей структурой

           doc.Load("book2.xml");

           // создать новый элемент 'book'

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

           // создать новый элемент 'title'

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

           newTitle.InnerText = txtName.Text;

           newBook.AppendChild(newTitle);

           // создать новый элемент author

           XmlElement newAuthor = doc.CreateElement("AUTHOR");

           newAuthor.InnerText = txtAuthor1.Text;

           newBook.AppendChild(newAuthor);

           if (txtAuthor2.Text.Length != 0)

           {

               XmlElement newName = doc.CreateElement("AUTHOR");

               newAuthor.InnerText = txtAuthor2.Text;

               newBook.AppendChild(newAuthor);

           }

           // создать новый элемент Binding

           XmlElement newBind = doc.CreateElement("BINDING");

           newBind.InnerText = txtPub.Text;

           newBook.AppendChild(newBind);

           //

           XmlElement newPages = doc.CreateElement("PAGES");

           newPages.InnerText = txtPages.Text;

           newBook.AppendChild(newPages);

           //

           XmlElement newPrice = doc.CreateElement("price");

           newPrice.InnerText = txtPrice.Text;

           newBook.AppendChild(newPrice);

           // добавить к текущему документу

           doc.DocumentElement.AppendChild(newBook);

           // записать doc на диск

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

           tr.Formatting = Formatting.Indented;

           doc.WriteContentTo(tr);

           tr.Close();

           // загрузить listBox1 со всеми заголовками, включая новый

           listBox1.Items.Clear();

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

           foreach (XmlNode node in nodeLst) listBox1.Items.Add(node.InnerText);

      }

Если нужно создать документ с самого начала, можно использовать класс XmlTextWriter. Можно также использовать XmlDocument. Какой из них выбрать? Если данные, которые желательно поместить в XML, доступны и готовы для записи, то самым подходящий будет класс XmlTextWriter. Однако, если необходимо создавать документ XML постепенно, вставляя узлы в различные места, то наиболее приемлемым будет применение XmlDocument.

3. Обработка атрибутов

Обычно атрибуты не рассматриваются как часть структуры документа.  Но, при необходимости, можно определить их наличие и извлечь значения. Для извлечения и записи атрибутов можно (как для элементов) использовать классы XmlReader, XmlWriter, а также XmlDocument.

3.1. Извлечение атрибутов с помощью XmlReader

В таблице перечислены некоторые свойства и методы для обработки атрибутов.

HasAttributes

свойство. Возвращает значение true, если элемент имеет атрибуты и false – если нет

AttributeCount

свойство. Сообщает сколько атрибутов  имеет элемент

GetAttribute()

метод. Извлекает атрибут по имени или по индексу

MoveToFirstAttribute()

метод. Позволяет перейти к первому атрибуту

MoveToNextAttribute()

метод. Позволяет перейти к следующему атрибуту

Для демонстрации этих возможностей добавим в XML-файл booknew.xml в элемент book атрибуты:

<?xml version="1.0" encoding="utf-8"?>

<Catalog>

 <book genre="Программная инженерия"  yearpublic="2006" >

   <title>Основы инженерии качества программных систем</title>

   <author>

     <name>Коротун Т.М.</name>

     <name>Коваль Г.И.</name>

   </author>

   <price>120.00</price>

 </book>

</Catalog>

Откроем предыдущий проект Windows-XML.

Добавим на форму еще одну кнопку для извлечения атрибутов из элемента book. В обработчик кнопки вставим код:

       private void btnAttr_Click(object sender, EventArgs e)

       {

           //извлечение атрибутов из элемента

           richTextBox1.Clear();

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

               //чтение узлов

           while (rdr.Read())

           {

               //проверить, не является ли он узлом

               if (rdr.NodeType == XmlNodeType.Element)

               {

               //Если это элемент, проверит его атрибуты

                   for (int i = 0; i < rdr.AttributeCount; i++)

                   {

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

                   }

               }

     

           }

           rdr.Close();

       }

3.2. Вставка атрибутов  в документ с помощью XmlWriter

Добавим на форму кнопку WriteAttributes. Обработчик кнопки создает новый файл booknew.xml, в котором размещается документ Catalog, состоящий из одного вложенного элемента  book. В элементе book есть два атрибута "genre" и "yearpublic". Метод WriteAttributeString() добавляет атрибут к элементу.

    private void btmWriteAtt_Click(object sender, EventArgs e)

       {

           // запись в файл с атрибутами

           XmlWriterSettings setting = new XmlWriterSettings();

           setting.Indent = true;

           string fname = "booknew.xml";

           XmlTextWriter writer = new XmlTextWriter(fname, null);

           writer.Formatting = Formatting.Indented;

           writer.WriteStartDocument();

           //начало создания єлементов

           writer.WriteStartElement("Catalog");

           writer.WriteStartElement("book");

           writer.WriteAttributeString("genre", "Программная инженерия");

           writer.WriteAttributeString("yearpublic", "2006");

           writer.WriteElementString("title", "Основы инженерии качества программных систем");

           writer.WriteStartElement("author");

           writer.WriteElementString("name", "Коротун Т.М.");

           writer.WriteElementString("name", "Коваль Г.И.");

           writer.WriteEndElement();

           writer.WriteElementString("price", "120.00");

           writer.WriteEndElement();

           writer.WriteEndElement();

           writer.WriteEndDocument();

           //Очистка потока

           writer.Flush();

           writer.Close();

       }

В результате  будет создан файл booknew.xml, содержащий описание книги.

Другой способ добавления и извлечения атрибутов – применение модели DOM (класс XmlDocument).

Выводы

Классы C# обеспечивают разные способы обработки Xml-документов. Кроме рассмотренных в лекции, в .NetFramework есть классы для создания схем документов, проверки документов  на соответствие схеме, поиск информации по содержимому(XPath и XslTransform), обработку запросов, взаимодействие с базой данных.


 

А также другие работы, которые могут Вас заинтересовать

67392. СОЦИААЛЬНЫЕ ГРУППЫ 85 KB
  Для индивида непосредственный контакт с социальной реальностью - это взаимодействие с окружающей его социальной группой. Именно группа для индивида является представителем общества в целом, его требований и интересов, именно г группа от лица всего общества предлагает индивиду социальные гарантии и блага.
67393. СОЦИААЬНАЯ СТРАТИФИКАЦИЯ 105 KB
  Но отсюда вовсе не следует что все статусы возникшие как продукт социальной дифференциации расположены в иерархическом порядке: некоторые из них например возрастные если рассматривать их в чистом виде без наложения других не содержат оснований социального неравенства в частности статус...
67394. СОЦИАЛЬНАЯ МОБИЛЬНОСТЬ 54.5 KB
  Вопрос о социальном неравенстве всегда влечет за собой вопрос, может ли индивид своими силами добиться повышения своего социального статуса и влиться в состав социального слоя, более высокого, чем его собственный на шкале обеспеченности и престижа.
67395. ОБЩЕСТВО 99 KB
  И хотя существует даже культура отшельничества когда люди годами и десятилетиями живут в одиночестве и удалении от общества это вовсе не означает победы асоциальности: в своем одиночестве отшельники занимаются именно тем что решают глобальные общечеловеческие вопросы и молятся за все человечество...
67396. ТИПЫ ОБЩЕСТВ 86 KB
  Так у Гегеля стадии развития общества совпадают со стадиями и фазами движения к самому себе абсолютного логического понятия лежащего в основе мира. Маркса типология обществ основывается на естественно-историческом подходе согласно которому все общества без исключения рано или поздно...
67397. Программное обеспечение: понятия и цели 67.5 KB
  Программные средства, принятые в производство, изготавливаются по утвержденной в установленном порядке технологии. Они должны соответствовать утвержденным техническим условиям и действующей нормативно-технической документации, обеспечиваться гарантиями поставщика.
67398. Проектирование полиграфического производства 760 KB
  В результате работы была составлена составлена технологическая характеристика издания, определено издательско-полиграфическое оформление данного издания, сделан выбор оборудования и расходных материалов для печати изделия образца, создана схема комплексного процесса
67399. Технология приготовления вторых горячих блюд из овощей 495.5 KB
  Продукты питания оцениваются по пищевой, биологической и энергетической ценности. Под пищевой ценностью продукта подразумевают содержание в нем пищевых веществ и степень их усвоения организмом, а также вкусовые достоинства.
67400. Мультипликация как технология развития творческих способностей подростков 1.2 MB
  Интеграция разных видов изобразительного искусства: рисунок, живопись, лепка, дизайн и декоративно-прикладное творчество сосуществуют в мультипликации на равных. А сам процесс создания мультфильма включает занятия литературные