Как прекратить парсинг XML-документа с помощью LIBXML SAX в любое время?

У меня есть Win32 C ++ код, который использует парсер LIBXML SAX. Этот код анализирует большой XML-файл (> 1 ГБ) и проверяет его с помощью схемы xsd. Когда возникает ошибка проверки xsd, LIBXML вызывает обратный вызов и продолжает анализ. Я хочу остановить процесс синтаксического анализа в этом обратном вызове. До сих пор я достигаю этого результата, поднимая исключение c ++. Но такой подход оставляет неизданные ресурсы и вызывает утечки памяти.

SAX Запуск кода:

xmlSchemaParserCtxtPtr  sch = xmlSchemaNewParserCtxt("MUXGate.xsd");
xmlSchemaPtr schema = xmlSchemaParse(sch);
xmlSchemaValidCtxtPtr vsch = xmlSchemaNewValidCtxt(schema);
context.vsch = xmlSchemaNewValidCtxt(schema);
xmlSchemaSetValidErrors(
vsch,
xmlMySchemaValidityErrorFunc,
xmlMySchemaValidityWarningFunc,
&context);

xmlSAXHandlerPtr hndlrptr = &my_handler;
void* ctxptr = &context;
xmlSchemaSAXPlugPtr saxPlug = xmlSchemaSAXPlug(vsch,&hndlrptr,&ctxptr);try{
if (xmlSAXUserParseFile(hndlrptr, ctxptr , "errschema.xml1") < 0) {
xmess<<"Parse error\n";
} else
xmess<<"Parse ok\n";

if(context.SchemaError)
{
xmess <<"Schema error\n";
}
}
catch(...) //Catching exception
{
xmess<<"Exception\n";
}

xmlSchemaSAXUnplug(saxPlug);
xmlSchemaFreeValidCtxt(context.vsch);
xmlSchemaFreeValidCtxt(vsch);
xmlSchemaFree(schema);
xmlSchemaFreeParserCtxt(sch);

Обратный вызов ошибки схемы:

void    xmlMySchemaValidityErrorFunc    (void * ctx,
const char * msg,
...)
{
MyContext& context = *(MyContext*)ctx;
context.SchemaError = true;

char buf[1024];
va_list args;

va_start(args, msg);
int len = vsnprintf_s(buf, sizeof(buf), sizeof(buf)/sizeof(buf[0]), msg, args);
va_end(args);

puts(buf);

throw new int(1); //throwing an exception
}

Есть функция void xmlStopParser (xmlParserCtxtPtr ctxt) но в функции обратного вызова ошибки схемы отсутствует контекст синтаксического анализатора.

Пожалуйста помоги!
Спасибо!

1

Решение

Я знаю, что вы опубликовали это давным-давно, так что вам может быть все равно, но у меня была похожая проблема. В случае, если кто-то столкнется с этим, я думаю, что ответ использует контекст push. Здесь вы постоянно помещаете новые данные в парсер. Когда вы сталкиваетесь с ошибкой, вы можете перестать выдвигать данные и звонить бесплатно. Вот пример кода из libSml2 testSAX.c:

if (sax2)
ctxt = xmlCreatePushParserCtxt(debugSAX2Handler, NULL,
chars, ret, filename);
else
ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
chars, ret, filename);
while ((ret = fread(chars, 1, 3, f)) > 0) {
xmlParseChunk(ctxt, chars, ret, 0);
}
ret = xmlParseChunk(ctxt, chars, 0, 1);
xmlFreeParserCtxt(ctxt);
0

Другие решения


По вопросам рекламы [email protected]