Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11855
Последний выпуск: 19.06.2015

Использование 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).

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
52K
02 сентября 2009 года
Верон
1 / / 02.09.2009
Мне нравитсяМне не нравится
19 сентября 2009, 21:42:55
Впервые вижу такую статью!
2.
26K
13 февраля 2007 года
Kanat Taumenov
0 / / 13.02.2007
Мне нравитсяМне не нравится
12 декабря 2007, 15:30:10
хотел сказать только "кг/ам", постеснялся..

скажу просто
автор неасилил xml и подобные УЖЕ ИМЕЮЩИЕСЯ форматы,спроектированные головастыми дядями :)
почитай про JSON кстати

3.
34K
11 ноября 2007 года
LiteCat
0 / / 11.11.2007
Мне нравитсяМне не нравится
11 ноября 2007, 15:50:51
а я до сих пор люблю Си:) если автор не поленится и сделает на C++, то будет интересно
4.
31K
19 июля 2007 года
BlackHeretic
0 / / 19.07.2007
Мне нравитсяМне не нравится
11 ноября 2007, 13:57:54
Сишная библиотека??? А на ассемблере нет? :) В двадцать первом веке живем все таки :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог