■ Модели однонаправленной обработки требуют использования более сложных программных моделей, реализующих навигацию и операции поиска в сложных документах. Написание кода универсального синтаксического анализатора, который работал бы с произвольными иерархиями XML, может вызывать большие трудности. Чтобы найти искомую информацию, вам придется использовать очень сложное состояние, позволяющее определять, в каком узле дерева документа вы находитесь. Так, если вы осуществляете поиск дескриптора , находящегося внутри определенного дескриптора , и в вашем XML-документе имеются дескрипторы , соответствующие объектам , и , которые могут присутствовать в XML-дереве на иерархических уровнях различной глубины, то для того, чтобы иметь возможность различать эти случаи и тем caмым гарантировать, что вы получаете корректную информацию, вам придется написать код, отслеживающий, в каком месте документа в настоящее время осуществляется просмотр. Если документ следует единственной корректно- определенной схеме, то, возможно, это не так уж плохо. С другой стороны, если документ может быть подготовлен с использованием одной из нескольких возможных схем, то задача становится алгоритмически сложной. В случае особо сложных документов следует рассмотреть вариант выполнения обработки на сервере, ибо там предоставляются не только более мощные вычислительные возможности, но и более мощные API-интерфейсы, предназначенные для проведения поиска в XML-документах (например, XPATH, поддерживающий запросы данных документа).
Ниже приведен простой код, предназначенный для чтения и записи представленных ранее данных с использованием модели однонаправленной обработки 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: Имя пользователя, которое мы хотим сохранить