2015-08-26 30 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

谢谢,无论如何! –