обработка ошибок libxml2

Я пишу небольшую обертку вокруг libxml2 на C++ и пытаюсь понять, как обрабатывать ошибки. А пока, допустим, я просто хочу их распечатать. Вот что у меня есть на данный момент:

Моя функция обработки ошибок:

void foo(void *ctx, const char *msg, ...) {
  cout << msg << endl;
  return;
}

Инициализировал так:

xmlGenericErrorFunc handler = (xmlGenericErrorFunc)foo;
initGenericErrorDefaultFunc(&handler);

Однако, если я разбираю неверный XPath, я получаю следующий вывод:

%s

Без кода обработки ошибок я получаю следующее:

XPath error : Invalid expression
//.@foobar
    ^

Очевидно, что в конечном итоге моя обработка ошибок будет делать больше, чем просто распечатывать сообщение об ошибке (оно будет регистрировать его в базе данных или что-то в этом роде), но на данный момент - как я могу получить эту строку ошибки?


person Dominic Rodger    schedule 05.11.2009    source источник


Ответы (2)


Три точки в конце списка аргументов для вашей функции foo() означают, что она принимает переменное количество аргументов. Чтобы иметь возможность печатать их, вы можете сделать что-то вроде этого (не проверено):

#include <stdarg.h>

#define TMP_BUF_SIZE 256
void foo(void *ctx, const char *msg, ...) {
   char string[TMP_BUF_SIZE];
   va_list arg_ptr;

   va_start(arg_ptr, msg);
   vsnprintf(string, TMP_BUF_SIZE, msg, arg_ptr);
   va_end(arg_ptr);
   cout << string << endl;
   return;
}
person Puppe    schedule 05.11.2009
comment
Это почти все - это дает мне недопустимое выражение, но не остальное. - person Dominic Rodger; 05.11.2009
comment
Это, вероятно, все, что содержится в сообщении, вы сказали, что получили %s, когда вы только напечатали msg, что указывает на то, что есть только один аргумент, указанный для foo(), и это строка для печати. Может информация здесь поможет вам? xmlsoft.org/html/libxml-xmlerror.html#xmlGenericErrorFunc - person Puppe; 05.11.2009
comment
@Puppe - это имеет смысл. К сожалению, не так много документации о том, что передается в xmlGenericErrorFunc. Хотя то, что у вас есть, достаточно хорошо для моих целей. Спасибо! - person Dominic Rodger; 05.11.2009

Как уже указывалось, если это ваша функция обработки:

#define TMP_BUF_SIZE 256
void err(void *ctx, const char *msg, ...) {
   char string[TMP_BUF_SIZE];
   va_list arg_ptr;
   va_start(arg_ptr, msg);
   vsnprintf(string, TMP_BUF_SIZE, msg, arg_ptr);
   va_end(arg_ptr);
   cout << string << endl;
   return;
}

вы можете установить его с помощью этой функции libxml2

xmlSetGenericErrorFunc(NULL,gemXmlGenericErrorFunc);

если у вас есть контекст для передачи, т. е. некоторая структура, данные, класс, любой указатель, приведенный к void *, вы можете поместить его в качестве первого аргумента.

Обратите внимание, что foo будет вызываться много раз, например, если вы получаете ошибку синтаксического анализа каждый раз, когда libxml добавляет строку в сообщение об ошибке.

person Trismegisto    schedule 04.03.2010