CodeNet / Языки программирования / C / C++ / Microsoft Visual C++ / Работа с текстом и строками
CodeNet / Приложения / Алгоритмы / Разбор выражений. Компиляторы и интерпретаторы.
CodeNet / Остальное / Форматы файлов
Использование XF в конфигурационных файлах
XF - это лёгкий и переносимый текстовый формат обмена данными. Он лаконичен и гибок, что позволяет его использовать в файлах конфигурации ПО. XF полностью поддерживает стандарт Unicode что делает его пригодным для создания локализованных приложений.
Есть конфигурационный файл для нашей программы:
Conf { Limits { MaxMemory = 1024; MaxUsers = 200; MaxThreads = 100; } Info { Title = "Sample Application 1.0"; WelcomeMessage = "You are welcome!!!"; } Users { Maxim { Password = "passwd"; LastLogin = "25.05.2007"; } Andrew { Password = "mysecret"; LastLogin = "23.08.2007"; } } }
Раздел Limits содержит ограничения на размер памяти, число пользователей, потоков и т п. Раздел Users содержит список пользователей с паролями, и датой последнего входа.
Для начала попробуем считать файл конфигурации conf.xf. Для работы с XF будем использовать библиотеку XFLib (она работает в Windows и Linux, а также любой Unix-системе, поддерживающей GCC). Скачать XFLib можно здесь: http://xfhome.org/?page=soft
Для подключения библиотеки XFLib к проекту, необходимо включить её в проект (для Windows - подключить файл xflib.lib к проекту), и включить в проект заголовочные файл xf.h и xf_api.h (из каталога lib в папке с XFLib).
xfMap *conf; int result; conf = xfCreate(); if (conf) { printf("Недостаточно памяти для чтения конфигурации"); exit(1); } result = xfReadFile(conf, "conf.xf"); if (result) { printf("Ошибка чтения конфигурации: %S (строка %i колонка %i)\n", xfError(conf),xfErrorLine(conf),xfErrorCol(conf)); exit(1); }
Здесь мы инициализировали структуру conf типа xfMap (которая будет содержать разобранный документ XF), считали в неё файл "conf.xf". Как видно из примера, мы выводим сведения о возможной ошибке разбора (если конфигурационный файл не является корректным документом XF).
Далее нам надо проанализировать содержимое считанного документа. Каждый документ XF - это дерево элементов, и его анализ заключается в прохождении дерева или отдельных его участков. Элемент документа в XFLib имеет тип xfNode, а для указания на элемент используется указатель xfNode*. Указатель на корень дерева XF (это несуществующий на самом деле глобальный элемент без названия, из которого исходят глобальные элементы) находится в поле root структур xfMap.
Работа с элементом производится по его указателю. Имея указатель на элемент можно получить или изменить его название, класс, значение, удалить элемент или получить доступ к его потомкам. Попробуем получить значение некоторых элементов:
xfNode *c; int MaxMemory, MaxUsers, MaxThreads; xfChar *Title, *WelcomeMessage; c = conf->root; c = xfEnter(c, L"Conf"); c = xfEnter(c, L"Limits"); MaxMemory = xfDecToInt(xfGet(xfEnter(c, L"MaxMemory"))); MaxUsers = xfDecToInt(xfGet(xfEnter(c, L"MaxThreads"))); MaxThreads = xfDecToInt(xfGet(xfEnter(c, L"MaxUsers"))); c = conf->root; c = xfEnter(c, L"Conf"); c = xfEnter(c, L"Info"); Title = xfDecToInt(xfGet(xfEnter(c, L"Title"))); WelcomeMessage = xfDecToInt(xfGet(xfEnter(c, L"WelcomeMessage")));
Обратите внимание, XFLib оперирует с Unicode-строоками, потому перед строками ставится символ L (как принято в языке Си для Unicode-строк). Кстати, вывод Unicode-сток в printf-подобных функциях производится спецификатором %S (а не %s).
В примере мы получили указатель на корень документа (conf->root), затем получили указатель на его потомка (xfEnter возвращает указатель на дочерний элемент по указателю на элемент-предок и имя дочернего элемента). Функция xfGet получает значение элемента по его указателю, xfDecToInt - специальные функции преобразования Unicode-строки в целое число.
Теперь у нас есть ещё одна задача: получить все элементы-потоки Users (они являются логинами пользователей нашей программы). Для получения первого потомка элемента есть функция xfChild():
c = xfEnter(xfEnter(c->root, L"Conf"), L"Users"); xfNode *p = xfChild(с);
Если возвращён нулевой указатель (XF_NULL), значит элемент не имеет потомков. Для получения брата элемента (следующего потомка общего родителя) есть функция xfNext(). Если возвращён нулевой указатель (XF_NULL), значит текущий элемент является последним потомком своего родителя.
Попробуем вывести список пользователей нашей программы (имя элемента получаем функцией xfName()):
c = xfEnter(xfEnter(c->root, L"Conf"), L"Users"); xfNode *p = xfChild(с); while (p) { printf("%S\n",xfName(c)); c = xfNext(c); }
Как видите, не очень удобно углубляться в дерево документа при помощи функции xfEnter - за один её вызов можно углубиться лишь на один уровень - до потомка текущего элемента. В XFLib есть функция xfEnterPath(), которая позволяет углубиться в дерево сразу на несколько элементов:
xfNode *p = xfEnterPath(conf->root, L"Conf Users"); int size = xfGet(xfEnterPath(conf->root, L"Conf Limits MaxMemory");
Как видно, формат XF можно использовать для хранения конфигурации приложений. Он достаточно гибок для хранения любых структур данных, и при этом просто читается и легко обрабатывается.
Ссылки
Любые вопросы по XF и XFLib можете направлять на электронную почту max@xfhome.org (Волков Максим).
- Сайт проекта XFHome.org (http://xfhome.org). Разработка и стандартизация формата XF, разработка программного обеспечения для работы с XF и документации.
- Введение в XF за 15 минут (http://xfhome.org/?page=15mins). Очень краткое введение в XF.
- Формат обмена данными XF, ревизия 5 (http://xfhome.org/files/xf_10.pdf).
- Библиотека XFLib для работы с XF (http://xfhome.org/?page=soft).
Оставить комментарий
Комментарии
скажу просто
автор неасилил xml и подобные УЖЕ ИМЕЮЩИЕСЯ форматы,спроектированные головастыми дядями :)
почитай про JSON кстати