Книга: Программирование мобильных устройств на платформе .NET Compact Framework

Листинг 10.3. Использование однонаправленного чтения-записи XML-данных для загрузки XML-документа из файла и его сохранения

Листинг 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);
  //Записать содержимое документа!
  //<Root>
  xmlTextWriter.WriteStartElement(XML_ROOT_TAG);
  //<Root>
  xmlTextWriter.WriteStartElement(XML_USERINFO_TAG);
  //<Root><UserID>
  //<Root><UserInfo>
  xmlTextWriter.WriteStartElement(XML_NAMEINFO_TAG);
  //<Root><UserInfo><Name>
  xmlTextWriter.WriteStartElement(XML_FIRSTNAME_TAG);
  //<Root><UserInfo><Name><FirstName>
  xmlTextWriter.WriteString(firstName); //Запись значения
  xmlTextWriter.WriteEndElement(); //Закрыть дескриптор имени
  //<Root><UserInfo><Name>
  xmlTextWriter.WriteStartElement(XML_LASTNAME_TAG);
  //<Root><UserInfo><Name><LastName>
  xmlTextWriter.WriteString(lastName); //Запись значения
  xmlTextWriter.WriteEndElement(); //Закрыть дескриптор фамилии
  //<Root><UserInfo><Name>
  xmlTextWriter.WriteEndElement(); //Закрыть дескриптор ФИО
  //<Root><UserInfo>
  //<Root><UserInfo>
  xmlTextWriter.WriteStartElement(XML_USERID_TAG);
  //<Root><UserInfo><UserID>
  //Запись значения
  xmlTextWriter.WriteString(userId.ToString());
  xmlTextWriter.WriteEndElement();
  //Закрыть дескриптор UserID
  //<Root><Userlnfo>
  xmlTextWriter.WriteEndElement(); //Закрыть дескриптор UserInfo
  //<Root>
  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;
   }
   //----------------------------------------------------
   //Здесь мы можем извлечь некоторый фактический текст и
   //получить данные, которые пытаемся загрузить
   //----------------------------------------------------
   case System.Xml.XmlNodeType.Text: {
    switch (currentReadLocation) {
    case ReadLocation.inFirstName: {
     firstName = xmlReader.Value;
     break;
    }
    case ReadLocation.inLastName: {
     lastName = xmlReader.Value;
     break;
    }
    case ReadLocation.inUserID: {
     userId = System.Convert.ToInt32(xmlReader.Value);
     break;
    }
    }
    break;
   }
   //-------------------------------------------------------------
   //Вызывается, когда встречается конец
   //элемента
   //
   //Мы можем захотеть переключить состояние в зависимости от вида
   //покидаемого узла, чтобы указать на то, что собираемся
   //вернуться назад к его предку
   //-------------------------------------------------------------
   case System.Xml.XmlNodeType.EndElement: {
    bool continueParsing;
    continueParsing = LoadHelper_EndElementEncountered(ref currentReadLocation);
    if (continueParsing ==false) {
     goto finished_reading_wanted_data;
    }
    break;
   }
   default: {
    //He страшно, если имеются XML-узлы других типов, но
    //в нашем примере работы с XML-документом мы должны
    //оповестить об этом факте...
    System.Windows.Forms.MessageBox.Show("Встретился непредвиденный XML-тип " + xmlReader.Name);
    break;
   }
   } //Конец оператора Case, используемого для определения текущего
   //типа XML-элeмeнтa, oбpaбaтывaeмoгo анализатором
   //Перейти к следующему узлу
   readSuccess = xmlReader.Read();
  }
  //Если мы оказались в этом месте программы, не покинув
  //XML-дескриптора UserInfo, то с XML-данными, которые
  //мы считываем, что-то не так
  throw new Exception("He найден элемент UserInfo в XML-документе!");
finished_reading_wanted_data:
  //Закрыть файл, поскольку работа с ним закончена!
  xmlReader.Close();
 }
 //--------------------------------------------------------
 //Вспомогательный код, ответственный за принятие решения
 //относительно того, в какое состояние необходимо перейти,
 //когда встречается закрывающий дескриптор
 //--------------------------------------------------------
 private static bool LoadHelper_EndElementEncountered(ref ReadLocation currentReadLocation) {
  switch (currentReadLocation) {
  //Если мы покидаем узел Name, то должны вернуться
  //обратно в узел UserInfo
  case ReadLocation.inName: {
   currentReadLocation = ReadLocation.inUserInfo;
   break;
  }
  //Если мы покидаем узел FirstName, то должны вернуться
  //обратно в узел Name
  case ReadLocation.inFirstName: {
   currentReadLocation = ReadLocation.inName;
   break;
  }
  //Если мы покидаем узел LastName, то должны вернуться
  //обратно в узел Name
  case ReadLocation.inLastName: {
   currentReadLocation = ReadLocation.inName;
   break;
  }
  //Если мы покидаем узел UserID, то должны вернуться
  //обратно в узел UserInfo
  case ReadLocation.inUserID: {
   currentReadLocation = ReadLocation.inUserInfo;
   break;
  }
  //Если мы покидаем узел UserInfo, то мы только что
  //закончили чтение данных в узлах UserID, FirstName
  //и LastName.
  //
  //Можно выйти из цикла, поскольку у нас уже есть вся
  //информация, которую мы хотели получить!
  case ReadLocation.inUserInfo: {
   return false; //Анализ должен быть прекращен
  }
  }
  return true; //Продолжить анализ
 }
 private static void LoadHelper_NewElementEncountered(string nodeName,ref ReadLocation currentReadLocation) {
  //------------------------------------------------------
  //Мы вошли в новый элемент!
  //
  //B какое состояние переход возможен, зависит от того, в
  //каком состоянии мы находимся в данный момент
  //------------------------------------------------------
  switch (currentReadLocation) {
  //Если мы находимся в узле AllMyData, то переход возможен
  //в узлы, которые указаны ниже
  case (ReadLocation.inAllMyData): {
   if (nodeName == XMI_USERINFO_TAG) {
    currentReadLocation = ReadLocation.inUserInfo;
   }
   break;
  }
  //Если мы находимся в узле UserInfo, то переход возможен
  //в узлы, которые указаны ниже
  case (ReadLocation.inUserInfo): {
   if (nodeName == XML_USERID_TAG) {
    currentReadLocation = ReadLocation.inUserID;
   } else if (nodeName == XML_NAMEINFO_TAG) {
    currentReadLocation = ReadLocation.inName;
   }
   break;
  }
  //Если мы находимся в узле Name, то переход возможен
  //в узлы, которые указаны ниже
  case (ReadLocation.inName): {
   if (nodeName == XML_FIRSTNAME_TAG) {
    currentReadLocation = ReadLocation.inFirstName;
   } else if (nodeName == XML_LASTNAME_TAG) {
    currentReadLocation = ReadLocation.inLastName;
   }
   break;
  }
  }
 } //Конец функции
} //Конец класса

Оглавление книги


Генерация: 2.461. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз