我有使用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)
但模式错误回调函数中没有解析器上下文。
请帮忙! 谢谢!
答案 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);