2015-08-26 31 views
1

我有使用LIBXML SAX解析器的win32 C++代碼。此代碼解析大XML文件(> 1Gb)並通過xsd模式驗證它。當xsd驗證錯誤引發LIBXML調用回調並繼續解析時。我想在這個回調中停止解析過程。到目前爲止,我通過提出C++異常來實現這個結果。但是這種方法會導致未釋放的資源並導致內存泄漏。如何在任何時候停止使用LIBXML SAX解析xml文檔?

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

我知道你很久以前發佈過這個,所以你可能不在乎,但是我也有類似的問題。如果其他人遇到它,我認爲答案是使用推送上下文。這是您不斷將新數據推送到解析器的地方。當您遇到錯誤時,您可以停止推送數據並撥打免費電話。下面是來自libxml2的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

謝謝,無論如何! –