本文介绍了libxml2获取验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用libxml2来针对xsd模式验证xml文件。
使用xmlSchemaSetParserErrors函数,错误输出到stderr。
我需要得到这些验证错误,将它们存储在内存中并显示给用户。
如何重定向这些错误?你能给我一些例子吗?
感谢,
Andrea

I am using libxml2 to validate an xml file against an xsd schema.Using xmlSchemaSetParserErrors function, errors are output to 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

推荐答案

此示例使用解析器模块的验证回调机制。 xmlSchemaSetParserErrors 期望的回调的签名似乎是相同的。

This example uses the validation callback mechanism of the parser module. The signature of callbacks expected by xmlSchemaSetParserErrors seems to be the same.

#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);
}

这篇关于libxml2获取验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 14:29