Главная » 2009 » Март » 20 » C# и XML. Удобный способ хранения данных. Часть первая
11:06
C# и XML. Удобный способ хранения данных. Часть первая
Было время, когда я скептически смотрел на возможность хранения данных в XML формате. Но когда рассмотрел подобную возможность более подробно и испробовал в работающих проектах, был приятно удивлен. При должном проектировании, получается довольно неплохая локальная база данных с быстрым доступом. А главное есть возможность установить не сложное взаимодействие с ней посредством C#. Разберем работу C# и XML на примере хранения логинов и паролей.
Создадим интерфейс для ввода логинов и паролей в локальную базу, а так же извлечения оных оттуда. База состоит из трех полей: id записи (id), логин (login) и пароль(password). На форме у нас будет 2 текстовых поля добавления (txtWLogin, txtWPassword), кнопка для добавления (btnWrite), поле для ввода айдишника, по которому будем выводить записи (txtID) и соответственно 2 поля для вывода найденных данных (txtRLogin, txtRPassword.). ID для каждой записи будет уникальным.
Во-первых, не забудем добавить пространства имен XML, IO для работы с XML документами и файлами соответственно:
XmlTextWriter xtw = new XmlTextWriter(filepath, Encoding.UTF32);
xtw.WriteStartDocument();
xtw.WriteStartElement("users");
xtw.WriteEndDocument();
xtw.Close();
}
Выше описана функция создания нового XML документа с входящим параметром в виде названия файла. В ней мы создаем объект XmlTextWriter, в котором указываем путь к файлу и кодировку документа. Далее создаем заголовок документа (“users”) и с помощью метода Close() закрываем объект. После закрытия, документ автоматически сохраняется. При создании и компиляции проекта данный файл у нас будет находиться в папке Debug (Visual Studio 2005)
Нужно учесть, что мы не всегда будем создавать новый документ, поэтому при загрузке формы необходимо проверять его наличие. Если файл отсутствует, то создаем его, если же файл уже создан, то функцию реализовывать мы не будем:
FileStream fs = new FileStream(filepath, FileMode.Open);
xd.Load(fs);
// Создаем новую запись USER c аттрибутом следующего id
XmlElement user = xd.CreateElement("user");
user.SetAttribute("id", “1”);
// Создаем 2 поля логин и пароль
XmlElement login = xd.CreateElement("login");
XmlElement pass = xd.CreateElement("password");
// Создаем 2 записи логина и пароля
XmlText tLogin = xd.CreateTextNode(name);
XmlText tPassword = xd.CreateTextNode(pwd);
login.AppendChild(tLogin); // Забиваем значение логина в поле LOGIN
pass.AppendChild(tPassword); // Забиваем значение пароля в поле PASSWORD
// Забиваем поля LOGIN и PASSWORD в запись USER
user.AppendChild(login);
user.AppendChild(pass);
// ЗАбиваем запись в документ
xd.DocumentElement.AppendChild(user);
fs.Close(); // Закрываем поток
xd.Save(filepath); // Сохраняем файл
}
Документ у нас должен состоять из основного объекта со свойством в виде айдишника и его дочерних объектов в виде логина и пароля. Выглядеть он будет так:
Думаю, с помощью комментариев в коде разобраться будет не сложно. Нужно только обратить внимание на значение поля ID. В данном случае мы забиваем единицу, но это только для примера. Как было сказано выше, это поле у нас будет уникальным, и поэтому функцию добавления айдишника я опишу немного позже. Сейчас приступим к разбору функции чтения данных из файла.
Чтение из документа.
Попробуем вывести запись логина и пароля из документа по ее айдишнику:
string name, pwd; // Новые переменные имени и пароля
// Объявляем и забиваем файл в документ
XmlDocument xd = new XmlDocument();
FileStream fs = new FileStream(filepath, FileMode.Open);
xd.Load(fs);
XmlNodeList list = xd.GetElementsByTagName("user"); // Создаем и заполняем лист по тегу "user"
for (int i = 0; i < list.Count; i++)
{
XmlElement id = (XmlElement)xd.GetElementsByTagName("user")[i]; // Забиваем id в переменную
XmlElement user = (XmlElement)xd.GetElementsByTagName("login")[i]; // Забиваем login в переменную
XmlElement pass = (XmlElement)xd.GetElementsByTagName("password")[i]; // Забиваем password в переменную
if (id.GetAttribute("id") == pid) // Если наткнулся на нужный айдишник
{
// Вставляем в переменные текст из тегов
name = user.InnerText;
pwd = pass.InnerText;
// Заполняем поля на форме
txtRLogin.Text = name;
txtRPassword.Text = pwd;
break;
}
else
{
// Чистим поля на форме
txtRLogin.Text = "";
txtRPassword.Text = "";
}
}
// Закрываем поток
fs.Close();
}
Итак. Входящие параметры – файл и айдишник, по которому будем искать в базе значения. ID вводится в специальное поле на форме (это если кто забыл). Как и в функции записи создаем объекты XML документа и «файлового» потока. Забиваем файл в документ. Создаем лист нужных нам элементов XML . В данный момент это главные элементы «user» с параметром ID. Далее запускаем цикл, который проверяет все значения ID. Во время цикла программа инициализирует новые элементы XmlElement. В момент, когда цикл натыкается на нужное нам значение айдишника, сразу новым переменным логина и пароля присваиваются найденные значения методом InnerText (находит текст, указанный в данном элементе). И заполняются соответственно поля на форме. Так как ID у нас уникален, программе больше искать нечего и цикл прерывается. Если ничего не находит значения в полях обнуляются. Ну и не забыть закрыть поток.
Как быть при чтении из документа выдает ошибку на строке FileStream fs = new FileStream(filepath, FileMode.Open); не может открыть файл так как его занят другой процесс?
Яша (23.06.2009 12:16) Как быть при чтении из документа выдает ошибку на строке FileStream fs = new FileStream(filepath, FileMode.Open); не может открыть файл так как его занят другой процесс?
Ошибка из-за string id = MaxID("users.xml"); я немного изменил private void WriteToXMLDocument(string filepath, string id,string name, string pwd) добавил string id дальше перед вызовом WriteToXMLDocument string id = MaxID("users.xml"); WriteToXMLDocument("users.xml",id, txtWLogin.Text, txtWPassword.Text); и будет счастье
Я не понимаю людей, которые для записи данных в xml сначала его целиком читают в память. Имхо, правильный ход - открывать файл для ДОЗАПИСИ и дописывать фрагменты xml. Соответственно, XmlWriter и XmlReader должны быть созданы в режиме ConformanceLevel.Fragment. Так же стоит, вероятно, почитать про immutable объекты данных.
Как купить карта клиента в в сеть немецких торговых центров МЕТРО Cash&Carry Москва 8(967)143-66-53 Официально по юридическому договору сделаем на физических лиц и сотрудников учереждений карты клиента метро в сеть немецких гипермаркетов "Метро":карточка metro обязательно с вашей фотографией(делается при вас в самом магазине Метро Кэш энд Керри),с номером,штрих - кодом,со специальной магнитной полосой, названием организации, от которой вы будете нами зарегистрированы и оформлены. Вы можете проводить с собой двоих человек. Карточки метро оформляются: на граждан Российской Федерации и иностранцев.Оформление производится без предоплаты, то есть вначале мы регистрируем и оформляем вас,вы получаете карточки metro, потом оплачиваете. Оплата производится в течение одного рабочего дня после оформления через Сбербанк ,немецкие магазины МЕТРО работают круглосуточно.Срок действия пропуска в метrо 3 года, по истечении этого срока договор перезаключается по взаимному согласию сторон.Для оказания этой услуги мы находим фирмы, у которых есть свободные места в этих супермаркетах,и заключаем с ними соответствующие договора, по которым фирмы обязуются предоставить вам право пользоваться их местами в этих магазинах сроком на три года. Регистрация производятся в разных немецких торговых центрах Metro CASH & CARRY, по выбору юридических лиц в соответствии с их территориальным месторасположением. Получив карты клиента метро в одном из немецких магазинов МETRO Cash&Cаrry вы можете ей пользоваться в любых других магазинах этой сети магазинов МETRO CASH and CARRY в РФ и за рубежом. Для заказа карты метро в сеть супермаркетов МETRO Cash and Cаrry звоните: 8(967)143-66-53