Книга: Программирование мобильных устройств на платформе .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
- Листинг 10.3. Использование однонаправленного чтения
- Листинг 10.3. Использование однонаправленного чтения-записи XML-данных для загрузки XML-документа из файла и его сохране...
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Восстановление с использованием инструмента gbak
- Типы страниц и их использование
- Использование констант
- Использование переменной окружения ISC_PATH
- Использование сервера Yaffil внутри процесса
- Использование CAST() с типами дата
- Использование типов содержимого и столбцов
- Вызов хранимых процедур InterBase с использованием стандартного синтаксиса ODBC
- Использование кнопки Автосумма