如何验证RapidJSON文档的子集?

如何验证RapidJSON文档的子集?,rapidjson,Rapidjson,我使用RapidJSON解析(大致)符合以下条件的消息。下面是一个此类消息的示例: { "method": "increment", "params": [ { "count": 42 } ] } 参数的内容取决于方法的值,因此。。。我需要针对method的每个可能值针对不同的模式进行验证。作为实现这一目标的一步,我创建了一个模式文档的映射,由方法键入名称: std::unordered_map<std::string, rapidjson::SchemaDocument

我使用RapidJSON解析(大致)符合以下条件的消息。下面是一个此类消息的示例:

{
    "method": "increment",
    "params": [ { "count": 42 } ]
}
参数的内容取决于
方法的值,因此。。。我需要针对
method
的每个可能值针对不同的模式进行验证。作为实现这一目标的一步,我创建了一个模式文档的映射,由
方法键入
名称:

std::unordered_map<std::string, rapidjson::SchemaDocument> schemas;
我的问题是:我知道如何验证
rapidjson::Document
,但不知道如何验证
GenericValue
实例(我收集
doc[“方法”]
返回的内容)

如何验证RapidJSON文档的片段或“子文档”

更新/解释:感谢@wsxedcrfv的回答,我现在意识到我的声明“我知道如何验证
rapidjson::Document
并不完全准确。我知道一种验证
rapidjson::Document
的方法。但显然,有不止一种方法可以做到这一点。为了给后代澄清一下这个问题,下面是我最初的问题中缺少的
validate()
函数:

bool validate(                                                                                                                                                                             
    rj::SchemaDocument const& schema,
    rj::Document *doc,
    std::string const& jsonMsg
)                  
{
    bool valid = false;              

    rj::StringStream ss(jsonMsg.c_str());

    rj::SchemaValidatingReader<
        rj::kParseDefaultFlags,
        rj::StringStream,
        rj::UTF8<>
    > reader(ss, schema);

    doc->Populate(reader);     

    if (!reader.GetParseResult()) {
        if (!reader.IsValid()) {                                  
            rj::StringBuffer sb;                        
            reader.GetInvalidSchemaPointer().StringifyUriFragment(sb);      
            printf("Message does not conform to schema!\n");
            printf("--------------------------------------------------------------------\n");
            printf("Invalid schema: %s\n", sb.GetString());
            printf("Invalid keyword: %s\n", reader.GetInvalidSchemaKeyword());
            sb.Clear();                                  
            reader.GetInvalidDocumentPointer().StringifyUriFragment(sb);    
            printf("Invalid document: %s\n", sb.GetString());
            printf("--------------------------------------------------------------------\n");
        } 

        else {
            printf("Message JSON is not well-formed!\n");
        }
    } 

    else {
        valid = true;
    }        

    return valid;
}

现在我知道了这个替代方法,我可以很容易地使用它对子文档/片段进行特定于上下文的验证

我想这个答案对你来说有点晚了,但这对我来说很有效:

    char json[] = "{ \"a\" : 1, \"b\" : 1.2  } ";
    rapidjson::Document d;
    std::cout << "parse json  error? " << d.Parse(json).HasParseError() << "\n";

    char schema[] = "{ \"type\" : \"integer\"  } ";
    rapidjson::Document sd;
    std::cout << "parse schema error? " << sd.Parse(schema).HasParseError() << "\n";
    rapidjson::SchemaDocument s{sd}; //sd may now be deleted

    rapidjson::SchemaValidator vali{s};
    std::cout << "json " << d.Accept(vali) << "\n"; // 0
    vali.Reset();
    std::cout << "a    " << d.GetObject()["a"].Accept(vali) << "\n"; // 1
    vali.Reset();
    std::cout << "b    " << d.GetObject()["b"].Accept(vali) << "\n"; // 0
charjson[]=“{\'a\':1,\'b\':1.2}”;
rapidjson::文档d;

谢谢,这正是我需要的。当我问这个问题的时候,我正在进行的项目现在已经完成了(我最终手工破解了一些手动验证代码),但是我绝对会用这些信息来清理我为新项目编写的代码谢谢!
#include "rapidjson/document.h"
#include <rapidjson/schema.h>
#include <iostream>


namespace rj = rapidjson;

namespace
{

std::string testMsg = R"msg({ "root": { "method": "control", "params": [ { "icc_delta_vol":  5 } ] } })msg";

std::string msgSchema = R"schema(
{
    "type": "object",

    "properties": {
        "method": { "$ref": "#/definitions/method" },
        "params": { "$ref": "#/definitions/paramsList" }
    },

    "required": [ "method", "params" ],

    "additionalProperties": false,

    "definitions": {
        // Omitted in the interest of brevity
        ...
    }
})schema";


} // End anonymous namespace

int main()
{
    rj::Document schemaDoc;

    if (schemaDoc.Parse(::msgSchema.c_str()).HasParseError()) {
        std::cout << "Schema contains invalid JSON, aborting...\n";
        exit(EXIT_FAILURE);
    }

    rj::SchemaDocument schema(schemaDoc);
    rj::SchemaValidator validator(schema);

    rj::Document doc;                                                                                                                                                                                                                     
    doc.Parse(::testMsg.c_str());

    std::cout << "doc.Accept(validator) = " << doc["root"].Accept(validator) << '\n';

    return 0;
    char json[] = "{ \"a\" : 1, \"b\" : 1.2  } ";
    rapidjson::Document d;
    std::cout << "parse json  error? " << d.Parse(json).HasParseError() << "\n";

    char schema[] = "{ \"type\" : \"integer\"  } ";
    rapidjson::Document sd;
    std::cout << "parse schema error? " << sd.Parse(schema).HasParseError() << "\n";
    rapidjson::SchemaDocument s{sd}; //sd may now be deleted

    rapidjson::SchemaValidator vali{s};
    std::cout << "json " << d.Accept(vali) << "\n"; // 0
    vali.Reset();
    std::cout << "a    " << d.GetObject()["a"].Accept(vali) << "\n"; // 1
    vali.Reset();
    std::cout << "b    " << d.GetObject()["b"].Accept(vali) << "\n"; // 0