Чтение и запись в XML фаил (C#)

Понедельник, Апрель 5th, 2010 | Программирование

1 звезда2 звезд3 звезд4 звезд5 звезд (23 голосов, средний: 4.74 из 5)
Loading ... Loading ...

Сейчас наиболее популярным форматом передачи данных является XML, по этому, я думаю, не стоит говорить об актуальности рассматриваемой проблемы ;) . Рано или поздно вам придется столкнуться с этим форматом.

Сегодня мы поговорим о том как читать/писать из/в XML фаил посредством классов входящих в .Net Framework. Скажу сразу, классов для работы с XML несколько, поэтому выбирать между ними все-таки придется :) .

Почему существует несколько классов для работы с одним и тем же? На этот вопрос, на мой взгляд, есть два ответа: «на вкус и цвет все фломастеры разные» и «в зависимости от предоставляемой функциональности один класс может оказаться удобнее в той или иной ситуации». Немного покопавшись в интернете и MSDN я нашел золотую парочку (для чтения и записи), о которой я вам сегодня и поведаю.

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

  1. Практически нулевой риск создать неправильный XML документ;
  2. Можно задать форматирование (отступы и д.р.) XML документа (очень сильно улучшает читаемость).

Итак, для начала надо решить, что вам надо сделать:

  1. Сформировать XML-документ одним проходом и не возвращаться к нему больше
  2. Прочитать/изменить уже существующий XML-документ

Зачем определяться? Скажем так, впоследствии это сэкономит ваше время при написании кода.

Наиболее подходящим для первого случая является класс XmlWriter. Плюсы данного класса:

  1. Форматирование результирующего XML документа;
  2. Создание открывающего и закрывающего тега в одну команду,причем для создания закрывающего тега не требуется знать имя открывающего (сомнительный плюс, но все же ;) ).

Для форматирования выводимого XML документа в XmlWriter используется класс XmlWriterSettings.

using System.Xml;
...
XmlWriterSettings settings = new XmlWriterSettings();
 
// включаем отступ для элементов XML документа
// (позволяет наглядно изобразить иерархию XML документа)
settings.Indent = true;
settings.IndentChars = "    "; // задаем отступ, здесь у меня 4 пробела
 
// задаем переход на новую строку
settings.NewLineChars = "\n"; 
 
// Нужно ли опустить строку декларации формата XML документа
// речь идет о строке вида "<?xml version="1.0" encoding="utf-8"?>"
settings.OmitXmlDeclaration = true;

Это не все параметры, остальные свойства класса XmlWiterSettings вы сможете найти в MSDN.

Так выглядит простейшее использование класса XmlWriter.

// FileName - имя файла, куда будет сохранен XML-документ
// settings - настройки форматирования (и не только) вывода
// (рассмотрен выше)
using (XmlWriter output = XmlWriter.Create(FileName, settings))
{
    ...
    // Создали открывающийся тег
    output.WriteStartElement("filialBD");
    // Добавляем атрибут для filialBD
    output.WriteAttributeString("deliver_id","10");
 
    // Создаем элемент <dname>sanchos</dname>
    output.WriteElementString("dname", "sanchos");
 
    ...
    // Закрываем filialBD
    output.WriteEndElement();
    ...
    // Сбрасываем буфферизированные данные
    output.Flush();
 
    // Закрываем фаил, с которым связан output
    output.Close();
}

Вот что получиться, если выполнить пример выше:

XML   
<?xml version="1.0" encoding="utf-8" ?>
<filialBD deliver_id="10">
    <dname>sanchos</dname>
</filialBD>

UPD. Используя функцию WriteElementString, вы не только открываете тег, записываете данные, но и ЗАКРЫВАЕТЕ его, поэтому добавить атрибут к такому элементу НЕЛЬЗЯ! Для решения данной проблемы используйте WriteStartElement,  WriteAttributeString, WriteEndElement.



Перейдем ко второму варианту развития событий – отредактировать/прочитать уже существующий XML-документ.

Для чтения XML-документа предусмотрен класс XMLReader, но он крайне не удобен, т.к осуществляет последовательное считывание и не позволяет «прыгать через»/обращаться сразу к нужному элементу.

Чтение и редактирование удобно производить через класс XmlDocument.

Давайте, для начала вспомним из чего состоит XML-документ:

  1. Строка вида <?xml … ?>
  2. Родительский элемент (он единственный и не повторимый :) )

Дальше, внутри родительского элемента располагаются элементы-потомки (child’ы) и т.д. по иерархии.

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

// Создаем экземпляр класса
XmlDocument xmlDoc = new XmlDocument();
 
// Загружаем XML-документ из файла
xmlDoc.Load(FileName);
 
// Загружаем XML-документ из строки
// xmlDoc.LoadXML(s1);
 
// Получаем всех детей корневого элемента
// xmlDoc.DocumentElement - корневой элемент
foreach (XmlNode table in xmlDoc.DocumentElement.ChildNodes)
{
    // перебираем все атрибуты элемента
    foreach (XmlAttribute attr in table.Attributes)
    {
        // attr.Name - имя текущего атрибута
        // attr.Value - значение текущего атрибута
        string s = attr.Name + ":" + attr.Value;
    }
 
    // перебираем всех детей текущего узла
    foreach (XmlNode ch in table.ChildNodes)
    {
        ...
    }
    // Получаем текст хранящийся в текущем узле
    MessageBox.Show(table.InnerText);
}

Теперь давайте рассмотрим как изменять уже имеющийся XML-документ.

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

// Создаем node
// book - имя узла
XmlNode node = xmlDoc.CreateElement("book");
 
// Добавляем его в качестве ребенка
parentNode.AppendChild(node);

Удаление узла производиться следующим образом:

// Удаление узла
parentNode.RemoveChild(node);

Примеры операции с атрибутами рассмотрены ниже:

// Создаем новый атрибут
// genre - имя атрибута
XmlAttribute newAttr = doc.CreateAttribute("genre");
newAttr.Value = "novel"; // Задаем его значение
// Добавляем атрибут в коллекцию атрибутов элемента
node.SetNamedItem(newAttr);
 
// Удаляем атрибут
node.Attributes.RemoveNamedItem("genre");
 
// Изменяем значение атрибута
XmlAttributeCollection Attribs = node.Attributes;
XmlAttribute attr = (XmlAttribute)Attribs.GetNamedItem("genre");
attr.Value = "fiction";

На первый взгляд, мне показалось крайне не логичным то, что для того чтобы создать node необходимо обращаться к методу CreateElement класса XmlDocument. Однако, мне кажется, что это сделано намерено -  в таком случае от экземпляра класса XmlDocument передаются все необходимые параметры (версия xml, кодировка и т.д.), которые необходимы при сохранении или экспорте XML-документа.

Итак, я дал вам пищу для ума и фантазии, это далеко не все, что можно сказать про XML-документ в контексте работы с ним в C#, однако это ступенька при помощи, которой вы сможете начать двигаться вперед ;) .

Удачи! :)

XmlDocum


Комментариев нет.

Оставить отзыв

Сначала зарегистрируйтесь.

Поиск по блогу