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

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

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

Option Strict On
Option Compare Binary
Imports System
Public Class SaveAndLoadXML UseReaderWriter
'XML-дескрипторы, которые мы будем использовать в своем документе
Const XML_ROOT_TAG As String = "AllMyData"
Const XML_USERINFO_TAG As String = "UserInfo"
Const XML_USERID_TAG As String = "UserID"
Const XML_NAMEINFO_TAG As String = "Name"
Const XML_FIRSTNAME_TAG As String = "FirstName"
Const XML_LASTNAME TAG As String = "LastName"
'Набор состояний, отслеживаемых по мере чтения данных
Private Enum ReadLocation
 inAllMyData
 inUserInfo
 inUserID
 inName
 inFirstName
 inLastName
End Enum
'--------------------------------------------------------------------
'Сохраняет пользовательское состояние
' [in] fileName: Имя файла, используемого для сохранения данных
' [in] userId: Идентификатор пользователя, который мы хотим сохранить
' [in] firstName: Имя пользователя, которое мы хотим сохранить
' [in] lastName: Фамилия пользователя, которую мы хотим сохранить
'--------------------------------------------------------------------
Public Shared Sub XML_SaveUserInfo(ByVal fileName As String, _
 ByVal userId As Integer, ByVal firstName As String, _
 ByVal lastName As String)
 Dim xmlTextWriter As System.Xml.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><UserInfo>
 xmlTextWriter.WriteEndElement()
 'Закрыть дескриптор UserInfo
 '<Root>
 xmlTextWriter.WriteEndElement() 'Закрыть дескриптор документа
 xmlTextWriter.Close()
End Sub
'--------------------------------------------------------------
'Загружает пользовательское состояние
' [in] fileName: Имя файла, используемого для сохранения данных
' [out] userId: Загруженный идентификатор пользователя
' [out] firstName: Загруженное имя пользователя
' [out] lastName: Загруженная фамилия пользователя
'--------------------------------------------------------------
Public Shared Sub XML_LoadUserInfo(ByVal fileName As String, _
 ByRef userId As Integer, ByRef firstName As String, _
 ByRef lastName As String)
 Dim currentReadLocation As ReadLocation
 'Начинаем с нулевых значении
 userId = 0
 firstName = ""
 lastName = ""
 Dim xmlReader As System.Xml.XmlTextReader = _
  New System.Xml.XmlTextReader(fileName)
 xmlReader.WhitespaceHandling = _
  System.Xml.WhitespaceHandling.None
 Dim readSuccess As Boolean
 readSuccess = xmlReader.Read()
 If (readSuccess = False) Then
  Throw New System.Exception("Отсутствуют XML-данные для чтения!")
 End If
 'Убедиться в том, что мы распознали корневой дескриптор
 If (xmlReader.Name <> XML_ROOT_TAG) Then
  Throw New System.Exception( _
   "Корневой дескриптор отличается от ожидаемого!")
 End If
 'Отметить текущее местоположение в документе
 currentReadLocation = ReadLocation.inAllMyData
 '------------------------------------------------------
 'Цикл прохождения документа и чтение необходимых данных
 '------------------------------------------------------
 While (readSuccess)
  Select Case (xmlReader.NodeType)
  'Вызывается при входе в новый элемент
  Case System.Xml.XmlNodeType.Element
   Dim nodeName As String = xmlReader.Name
   LoadHelper_NewElementEncountered(nodeName, _
    currentReadLocation)
   '--------------------------------------------------
   'Здесь мы можем извлечь некоторый фактический текст
   'и получить данные, которые пытаемся загрузить
   '--------------------------------------------------
  Case System.Xml.XmlNodeType.Text
   Select Case currentReadLocation
   Case ReadLocation.inFirstName
    firstName = xmlReader.Value
   Case ReadLocation.inLastName
    lastName = xmlReader.Value
   Case ReadLocation.inUserID
    userId = CInt(xmlReader.Value)
   End Select
   'Конец оператора Case "System.Xml.XmlNodeType.Text"
   '----------------------------------------------------
   'Вызывается, когда встречается конец
   'элемента
   '
   'Мы можем захотеть переключить состояние в зависимости
   'от вида покидаемого узла, чтобы указать на то, что
   'собираемся вернуться назад к его предку
   '-----------------------------------------------------
  Case System.Xml.XmlNodeType.EndElement
   Dim continueParsing As Boolean
   continueParsing = LoadHelper_EndElementEncountered( _
    currentReadLocation)
   If (continueParsing = False) Then
    GoTo finished_reading_wanted_data
   End If
  Case Else
   'He страшно, если имеются XML-узлы других типов, но
   'в нашем примере работы с XML-документом мы должны
   'оповестить об этом факте
   MsgBox( _
    "Встретился непредвиденный XML-тип " + xmlReader.Name)
  End Select 'Конец оператора Case, используемого для определения текущего
  'типа XML-элeмeнтa, oбpaбaтывaeмoгo анализатором
  'Перейти к следующему узлу
  readSuccess = xmlReader.Read()
 End While
 'Если мы оказались в этом месте программы, не покинув
 'XML-дескриптора UserInfo, то с XML-данными, которые мы считываем,
 'что-то не так
 Throw New Exception("He найден элемент UserInfo в XML-документе!")
finished reading_wanted_data:
 'Закрыть файл, поскольку работа с ним закончена!
 xmlReader.Close()
End Sub
'--------------------------------------------------------
'Вспомогательный код, ответственный за принятие решения
'относительно того, в какое состояние необходимо перейти,
'когда встречается закрывающий дескриптор
'--------------------------------------------------------
Private Shared Function LoadHelper_EndElementEncountered( _
 ByRef currentReadLocation As ReadLocation) As Boolean
 Select Case (currentReadLocation)
 'Если мы покидаем узел Name, то должны вернуться
 'обратно в узел UserInfo
 Case ReadLocation.inName
  currentReadLocation = ReadLocation.inUserInfo
 'Если мы покидаем узел FirstName, то должны вернуться
 'обратно в узел Name
 Case ReadLocation.inFirstName
  currentReadLocation = ReadLocation.inName
 'Если мы покидаем узел LastName, то должны вернуться
 'обратно в узел Name
  Case ReadLocation.inLastName
   currentReadLocation = ReadLocation.inName
 'Если мы покидаем узел UserID, то должны вернуться
 'обратно в узел UserInfo
 Case ReadLocation.inUserID
  currentReadLocation = ReadLocation.inUserInfo
 'Если мы покидаем узел UserInfo, то мы только что
 'закончили чтение данных в узлах UserID, FirstName
 'и LastName
 '
 'Можно выйти из цикла, поскольку у нас уже есть вся
 'информация, которую мы хотели получить!
 Case ReadLocation.inUserInfo
  Return False 'Анализ должен быть прекращен
 End Select
 Return True
 'Продолжить анализ
End Function
Private Shared Sub LoadHelper_NewElementEncountered( _
 ByVal nodeName As String, _
 ByRef currentReadLocation As ReadLocation)
 '----------------------------------------------------
 'Мы вошли в новый элемент!
 'В какое состояние переход возможен, зависит от того,
 'в каком состоянии мы находимся в данный момент
 '----------------------------------------------------
 Select Case (currentReadLocation)
 'Если мы находимся в узле AllMyData, то переход возможен
 'в узлы, которые указаны ниже
 Case (ReadLocation.inAllMyData)
  If (nodeName = XML_USERINFO_TAG) Then
   currentReadLocation = ReadLocation.inUserInfo
  End If
 'Если мы находимся в узле UserInfo, то переход возможен
 'в узлы, которые указаны ниже
 Case (ReadLocation.inUserInfo)
  If (nodeName = XML_USERID_TAG) Then
   currentReadLocation = ReadLocation.inUserID
  ElseIf (nodeName = XML_NAMEINFO_TAG) Then
   currentReadLocation = ReadLocation.inName
  End If
 'Если мы находимся в узле Name, то переход возможен
 'в узлы, которые указаны ниже
 Case (ReadLocation.inName)
  If (nodeName = XML_FIRSTNAME_TAG) Then
   currentReadLocation = ReadLocation.inFirstName
  ElseIf (nodeName = XML LASTNAME_TAG) Then
   currentReadLocation = ReadLocation.inLastName
  End If
 End Select
End Sub
End Class

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


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