C++ libxml2获取验证错误
我使用libxml2根据xsd模式验证xml文件。 使用xmlSchemaSetParserErrors函数,将错误输出到stderr。 我需要得到这些验证错误,将它们存储在内存中并显示给用户。 如何重定向这些错误?你能给我举几个例子吗? 谢谢C++ libxml2获取验证错误,c++,libxml2,C++,Libxml2,我使用libxml2根据xsd模式验证xml文件。 使用xmlSchemaSetParserErrors函数,将错误输出到stderr。 我需要得到这些验证错误,将它们存储在内存中并显示给用户。 如何重定向这些错误?你能给我举几个例子吗? 谢谢 Andrea此示例使用解析器模块的验证回调机制。xmlschemasetparserrors预期的回调签名似乎是相同的 #include <iostream> #include <cstdarg> #include <cst
Andrea此示例使用解析器模块的验证回调机制。
xmlschemasetparserrors
预期的回调签名似乎是相同的
#include <iostream>
#include <cstdarg>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <libxml/parser.h>
#include <libxml/tree.h>
struct ParserContext
{
ParserContext() : context(xmlNewParserCtxt()) {}
~ParserContext() { xmlFreeParserCtxt(context); }
xmlParserCtxtPtr context;
private:
ParserContext(ParserContext&);
void operator=(ParserContext&);
};
struct ErrorHandler
{
std::vector<std::string> errors;
void RegisterErrorHandling(xmlValidCtxt& validationContext)
{
// Change this to register for schema errors...
validationContext.userData = this;
validationContext.error = &ErrorHandler::Handle;
}
private:
static void Handle(void *handler, const char *format, ...)
{
va_list arguments;
va_start(arguments, format);
std::string message = MakeMessage(format, arguments);
va_end(arguments);
ErrorHandler* errorHandler = static_cast<ErrorHandler*>(handler);
errorHandler->errors.push_back(message);
}
static std::string MakeMessage(const char* format, va_list arguments)
{
const size_t bufferSize = 200;
std::vector<char> buffer(bufferSize, 0);
size_t charactersWritten =
vsnprintf(&buffer.front(), bufferSize, format, arguments);
if (charactersWritten == -1)
buffer.back() = 0; // Message truncated!
return std::string(&buffer.front());
}
};
struct XmlDocument
{
static XmlDocument FromFile(const char* fileName)
{
ParserContext parser;
ErrorHandler errorHandler;
errorHandler.RegisterErrorHandling(parser.context->vctxt);
XmlDocument document(xmlCtxtReadFile(
parser.context, fileName, NULL, XML_PARSE_DTDVALID));
document.errors = move(errorHandler.errors);
return document;
}
XmlDocument(XmlDocument&& other) :
xmlPointer(other.xmlPointer),
errors(move(other.errors))
{
other.xmlPointer = nullptr;
}
~XmlDocument()
{
xmlFreeDoc(xmlPointer);
}
xmlDocPtr xmlPointer;
std::vector<std::string> errors;
private:
XmlDocument(xmlDocPtr pointer) : xmlPointer(pointer) {}
XmlDocument(XmlDocument&);
void operator=(XmlDocument&);
};
void DisplayErrorsToUser(
const XmlDocument& document,
std::ostream& displayStream = std::cout)
{
using namespace std;
copy(begin(document.errors), end(document.errors),
ostream_iterator<string>(displayStream, "\n"));
}
int main()
{
auto xml = XmlDocument::FromFile("test.xml");
DisplayErrorsToUser(xml);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构解析上下文
{
ParserContext():上下文(xmlNewParserCtxt()){}
~ParserContext(){xmlFreeParserCtxt(上下文);}
xmlParserCtxtPtr上下文;
私人:
ParserContext(ParserContext&);
void运算符=(ParserContext&);
};
结构错误处理程序
{
向量误差;
无效注册表错误处理(xmlvalidctext和validationContext)
{
//将此更改为注册架构错误。。。
validationContext.userData=此;
validationContext.error=&ErrorHandler::Handle;
}
私人:
静态void句柄(void*句柄,const char*格式,…)
{
va_列表参数;
va_开始(参数、格式);
std::string message=MakeMessage(格式、参数);
va_end(参数);
ErrorHandler*ErrorHandler=static_cast(处理器);
errorHandler->errors.push_back(消息);
}
静态std::string MakeMessage(const char*格式,va_列表参数)
{
const size\u t bufferSize=200;
std::向量缓冲区(bufferSize,0);
大小\u t字符写入=
vsnprintf(&buffer.front(),bufferSize,format,arguments);
if(characterswrited==-1)
buffer.back()=0;//消息被截断!
返回std::string(&buffer.front());
}
};
结构XmlDocument
{
静态XmlDocument FromFile(常量字符*文件名)
{
ParserContext解析器;
错误处理程序错误处理程序;
errorHandler.RegisterErrorHandling(parser.context->vctxt);
xmlctdocument文档(xmlCtxtReadFile(
parser.context,fileName,NULL,XML_PARSE_DTDVALID));
document.errors=move(errorHandler.errors);
归还文件;
}
XmlDocument(XmlDocument&其他):
xmlPointer(其他.xmlPointer),
错误(移动(其他.错误))
{
other.xmlPointer=nullptr;
}
~XmlDocument()
{
xmlFreeDoc(xmlPointer);
}
xmlDocPtr-xmlPointer;
向量误差;
私人:
XmlDocument(xmlDocPtr指针):xmlPointer(指针){}
XmlDocument(XmlDocument&);
void运算符=(XmlDocument&);
};
无效显示错误用户(
常量XML文档和文档,
std::ostream&displayStream=std::cout)
{
使用名称空间std;
复制(开始(文档.错误),结束(文档.错误),
ostream_迭代器(displayStream,“\n”);
}
int main()
{
auto-xml=XmlDocument::FromFile(“test.xml”);
DisplayErrorsToUser(xml);
}
如API文档中所述,设置用于处理验证上下文错误的回调函数。
您需要针对定义的签名编写两个回调函数:
- 错误
- 警告
void err(void *ctx, const char *msg, ...)
{
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);
if(len==0) // Can't create schema validity error!
else // Do something to store `buf`,
// you may need to use void *ctx to achieve this
return;
}
那就打电话吧
xmlSchemaSetValidErrors(有效的ctxt\ptr,(xmlSchemaValidityErrorFunc)err,(xmlSchemaValidityWarningFunc)warn,ctx)代码>
打电话之前
xmlSchemaValidateDoc()
或者更简洁地说:
void err(void *ctx, const char *msg, ...)
{
va_list args;
va_start(args, msg);
char *val = va_arg(args,char*);
va_end(args);
}
val现在包含验证错误除非我遗漏了什么,否则可以使用xmlSchemaSetParserErrors()设置您自己的错误回调。那么,问题出在哪里,先生?没有问题,我只是想找一个关于如何为错误设置自定义回调的示例。