如何使用LIBXML SAX随时停止解析xml文档?

时间:2015-08-26 13:59:31

标签: c++ sax libxml2 saxparser

我有使用LIBXML SAX解析器的win32 c ++代码。此代码解析大xml文件(> 1Gb)并通过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 个答案:

答案 0 :(得分:1)

我知道你很久以前就贴了这个,所以你可能不在乎了,但我有类似的问题。如果其他人遇到它,我认为答案是使用推送上下文。这是您不断将新数据推送到解析器的地方。遇到错误时,您可以停止推送数据并拨打免费电话。以下是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);