Материал сайта coderlife.ru
Сейчас наиболее популярным форматом передачи данных является XML, по этому, я думаю, не стоит говорить об актуальности рассматриваемой проблемы. Рано или поздно вам придется столкнуться с этим форматом.
Сегодня мы поговорим о том как читать/писать из/в XML фаил посредством классов входящих в .Net Framework. Скажу сразу, классов для работы с XML несколько, поэтому выбирать между ними все-таки придется .
Почему существует несколько классов для работы с одним и тем же? На этот вопрос, на мой взгляд, есть два ответа: «на вкус и цвет все фломастеры разные» и «в зависимости от предоставляемой функциональности один класс может оказаться удобнее в той или иной ситуации». Немного покопавшись в интернете и MSDN я нашел золотую парочку (для чтения и записи), о которой я вам сегодня и поведаю.
Скажу сразу, я не рассматриваю ручное формирование результирующего XML-документа, разумеется оно быстрее, чем любой из классов, но это не всегда удобно. Несколько причин почему стоит использовать классы для генерации XML документа, а не создавать его вручную:
Практически нулевой риск создать неправильный XML документ;
Можно задать форматирование (отступы и д.р.) XML документа (очень сильно улучшает читаемость).
Итак, для начала надо решить, что вам надо сделать:
Сформировать XML-документ одним проходом и не возвращаться к нему больше
Прочитать/изменить уже существующий XML-документ
Зачем определяться? Скажем так, впоследствии это сэкономит ваше время при написании кода.
Наиболее подходящим для первого случая является класс XmlWriter. Плюсы данного класса:
Форматирование результирующего XML документа;
Создание открывающего и закрывающего тега в одну команду,причем для создания закрывающего тега не требуется знать имя открывающего (сомнительный плюс, но все же).
Для форматирования выводимого 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 version="1.0" encoding="utf-8" ?><filialBD deliver_id="10"> <dname>sanchos</dname></filialBD>
UPD. Используя функцию WriteElementString, вы не только открываете тег, записываете данные, но и ЗАКРЫВАЕТЕ его, поэтому добавить атрибут к такому элементу НЕЛЬЗЯ! Для решения данной проблемы используйте WriteStartElement, WriteAttributeString, WriteEndElement.
Перейдем ко второму варианту развития событий – отредактировать/прочитать уже существующий XML-документ.
Для чтения XML-документа предусмотрен класс XMLReader, но он крайне не удобен, т.к осуществляет последовательное считывание и не позволяет «прыгать через»/обращаться сразу к нужному элементу.
Чтение и редактирование удобно производить через класс XmlDocument.
Давайте, для начала вспомним из чего состоит XML-документ:
Строка вида <?xml … ?>
Родительский элемент (он единственный и не повторимый )
Дальше, внутри родительского элемента располагаются элементы-потомки (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#, однако это ступенька при помощи, которой вы сможете начать двигаться вперед .
Удачи!