2015-08-26 6 views
1

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

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), но нет никакого контекста парсер в функции схемы ошибки обратного вызова.

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

ответ

0

Я знаю, что вы опубликовали это давным-давно, так что вам может быть безразлично, но у меня была аналогичная проблема. В случае, если кто-то еще сталкивается с этим, я думаю, что ответ использует контекст push. Здесь вы непрерывно вводите новые данные в парсер. Когда вы сталкиваетесь с ошибкой, вы можете прекратить нажимать данные и называть их бесплатными. Вот пример кода из 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

Спасибо, во всяком случае! –

 Смежные вопросы

  • Нет связанных вопросов^_^