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