Ниже приведен простой код, предназначенный для чтения и записи представленных ранее данных с использованием модели однонаправленной обработки XML- документов с помощью объектов XMLReader и XMLWriter. Особый интерес для вас может представлять конечный автомат, используемый в объекте XMLReader для отслеживания текущего места в документе; заметьте, что даже для столь простого XML-документа, как наш, этот код вовсе не тривиален. В противоположность этому код, предназначенный для вывода XML-документов при помощи объекта XMLWriter, отличается простотой.
Листинг 10.3. Использование однонаправленного чтения-записи XML-данных для загрузки XML-документа из файла и его сохранения
using System;
public class SaveAndLoadXML UseReaderWriter {
//XML-дескрипторы, которые мы будем использовать в своем документе
const string XML_ROOT_TAG = "AllMyData";
const string XML_USERINFO_TAG = "UserInfo";
const string XMI_USERID_TAG = "UserID";
const string XML_NAMEINFO_TAG = "Name";
const string XML_FIRSTNAME_TAG = "FirstName";
const string XML_LASTNAME TAG = "LastName";
//Набор состояний, отслеживаемых по мере чтения данных
private enum ReadLocation {
inAllMyData,
inUserInfo,
inUserID,
inName,
inFirstName,
inLastName,
}
//--------------------------------------------------------------------
//Сохраняет пользовательское состояние
//
// [in] fileName: Имя файла, используемого для сохранения данных
// [in] userId: Идентификатор пользователя, который мы хотим сохранить
// [in] firstName: Имя пользователя, которое мы хотим сохранить
// [in] lastName: Фамилия пользователя, которую мы хотим сохранить
//--------------------------------------------------------------------
public static void XML_SaveUserInfo(string fileName, int userId,string firstName, string lastName) {
System.Xml.XmlTextWriter xmlTextWriter;
xmlTextWriter =new System.Xml.XmlTextWriter(fileName, System.Text.Encoding.Default);
//Записать содержимое документа!
//
xmlTextWriter.WriteStartElement(XML_ROOT_TAG);
//
xmlTextWriter.WriteStartElement(XML_USERINFO_TAG);
//
//
xmlTextWriter.WriteStartElement(XML_NAMEINFO_TAG);
//
xmlTextWriter.WriteStartElement(XML_FIRSTNAME_TAG);
//
xmlTextWriter.WriteString(firstName); //Запись значения
xmlTextWriter.WriteEndElement(); //Закрыть дескриптор имени
//
xmlTextWriter.WriteStartElement(XML_LASTNAME_TAG);
//
xmlTextWriter.WriteString(lastName); //Запись значения
xmlTextWriter.WriteEndElement(); //Закрыть дескриптор фамилии
//
xmlTextWriter.WriteEndElement(); //Закрыть дескриптор ФИО
//
//
xmlTextWriter.WriteStartElement(XML_USERID_TAG);
//
//Запись значения
xmlTextWriter.WriteString(userId.ToString());
xmlTextWriter.WriteEndElement();
//Закрыть дескриптор UserID
//
xmlTextWriter.WriteEndElement(); //Закрыть дескриптор UserInfo
//
xmlTextWriter.WriteEndElement(); //Закрыть дескриптор документа
//
xmlTextWriter.Close();
}
//--------------------------------------------------------------
//Загружает пользовательское состояние
//
// [in] fileName: Имя файла, используемого для сохранения данных
// [out] userId: Загруженный идентификатор пользователя
// [out] firstName: Загруженное имя пользователя
// [out] lastName: Загруженная фамилия пользователя
//--------------------------------------------------------------
public static void XML_LoadUserInfo(string fileName, out int userId, out string firstName,out string lastName) {
ReadLocation currentReadLocation;
//Начинаем с нулевых значений
userId = 0;
firstName = "";
lastName = "";
System.Xml.XmlTextReader xmlReader = new System.Xml.XmlTextReader(fileName);
xmlReader.WhitespaceHandling = System.Xml.WhitespaceHandling.None;
bool readSuccess;
readSuccess = xmlReader.Read();
if (readSuccess == false) {
throw new System.Exception("Отсутствуют XML-данные для чтения!");
}
//Убедиться в том, что мы распознали корневой дескриптор
if (xmlReader.Name != XML_ROOT_TAG) {
throw new System.Exception("Корневой дескриптор отличается от ожидаемого!");
}
//Отметить текущее местоположение в документе
currentReadLocation = ReadLocation.inAllMyData;
//------------------------------------------------------
//Цикл прохождения документа и чтение необходимых данных
//------------------------------------------------------
while (readSuccess) {
switch (xmlReader.NodeType) {
//Вызывается при входе в новый элемент
case System.Xml.XmlNodeType.Element: {
string nodeName = xmlReader.Name;
LoadHelper_NewElementEncountered(nodeName, ref currentReadLocation);
break;
}
//----------------------------------------------------
//Здесь мы можем извлечь некоторый фактический текст и
Читать дальше