[英]libxml2 get validation errors
I am using libxml2 to validate an xml file against an xsd schema. 我正在使用libxml2来针对xsd模式验证xml文件。 Using xmlSchemaSetParserErrors function, errors are output to stderr.
使用xmlSchemaSetParserErrors函数,错误将输出到stderr。 I need to get these validation errors, store them in memory and display to the user.
我需要获取这些验证错误,将它们存储在内存中并显示给用户。 How can I redirect these errors ?
如何重定向这些错误? Could you provide me some examples ?
你能给我一些例子吗? Thanks, Andrea
谢谢,安德里亚
This example uses the validation callback mechanism of the parser module. 本示例使用解析器模块的验证回调机制。 The signature of callbacks expected by
xmlSchemaSetParserErrors
seems to be the same. xmlSchemaSetParserErrors
期望的回调签名似乎相同。
#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);
}
Or even more concise: 或更简洁:
void err(void *ctx, const char *msg, ...)
{
va_list args;
va_start(args, msg);
char *val = va_arg(args,char*);
va_end(args);
}
val now contains validation errors val现在包含验证错误
As said in the API documentation, xmlSchemaSetParserErrors() Set the callback functions used to handle errors for a validation context.
如API文档中所述, xmlSchemaSetParserErrors()
Set the callback functions used to handle errors for a validation context.
You need to write two callback functions with respect to defined signature : 您需要针对已定义的签名编写两个回调函数:
An example could be : 例如:
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;
}
Then just call 然后打电话
xmlSchemaSetValidErrors(valid_ctxt_ptr, (xmlSchemaValidityErrorFunc) err, (xmlSchemaValidityWarningFunc) warn, ctx);
before calling 打电话之前
xmlSchemaValidateDoc()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.