JSON模式验证

34

是否有一个稳定的库可以根据模式验证JSON?

json-schema.org提供了一个实现列表。值得注意的是,缺少C和C++。

我找不到一个C ++ JSON模式验证器有什么原因?
没有人想要一种快速验证传入JSON文件的方法吗?


4
很可能是因为C和C++很少用于Web应用程序,而JSON的主要应用程序是Web应用程序。如果没有,您可以选择另一个并进行移植。 - Kaleb Brasee
6
JSON不仅适用于浏览器和Web服务器之间的通信,还可以用于存储偏好设置、系统之间的RPC等等。基本上,任何XML被(误)使用的地方都可以使用JSON。 - Mark Renouf
3
@Mark:确实,这正是我们的使用情况。我们需要一种存储复杂配置的方式(太复杂了,无法使用ini格式)。我们选择JSON而不是XML。 - deft_code
1
实现的列表现在包括 C 和 C++:http://json-schema.org/implementations.html#validator-cpp - Ida
7个回答

18

是否有一个稳定的库可以根据架构验证JSON?

我在谷歌上找到了一些结果:

您还可以将Python或Javascript解释器插入应用程序中,并简单地运行您已经找到的那些验证器实现的本机版本。

为什么我无法轻松找到C ++ JSON模式验证器?

我认为JSON起源于Web技术,而C / C ++已经不再适用于Web应用程序实现。


1
Chromium的验证器看起来非常不错,但在使用它之前,我想从Chromium的基础代码中提取模式。因此,它不是一个即插即用的解决方案,但比自己编写一个要好得多。 - deft_code
JSON Schema 网站 列出了一个 C 库(WJElement),但我没有任何使用它的经验,而且我相当确定它不支持最新版本的标准。 - cloudfeet

8

Valijson 是一款非常优秀的库,仅依赖于 Boost(我实际上希望 改变 这一点)。它甚至不依赖于任何特定的 JSON 解析器,提供了适配大多数常用库(如 JsonCpp、rapidjson 和 json11)的适配器。

代码可能看起来有些冗长,但你可以始终编写一个帮助程序(例如 JsonCpp):

#include <json-cpp/json.h>
#include <sstream>
#include <valijson/adapters/jsoncpp_adapter.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>

void validate_json(Json::Value const& root, std::string const& schema_str)
{
  using valijson::Schema;
  using valijson::SchemaParser;
  using valijson::Validator;
  using valijson::ValidationResults;
  using valijson::adapters::JsonCppAdapter;

  Json::Value schema_js;
  {
    Json::Reader reader;
    std::stringstream schema_stream(schema_str);
    if (!reader.parse(schema_stream, schema_js, false))
      throw std::runtime_error("Unable to parse the embedded schema: "
                               + reader.getFormatedErrorMessages());
  }

  JsonCppAdapter doc(root);
  JsonCppAdapter schema_doc(schema_js);

  SchemaParser parser(SchemaParser::kDraft4);
  Schema schema;
  parser.populateSchema(schema_doc, schema);
  Validator validator(schema);
  validator.setStrict(false);
  ValidationResults results;
  if (!validator.validate(doc, &results))
  {
    std::stringstream err_oss;
    err_oss << "Validation failed." << std::endl;
    ValidationResults::Error error;
    int error_num = 1;
    while (results.popError(error))
    {
      std::string context;
      std::vector<std::string>::iterator itr = error.context.begin();
      for (; itr != error.context.end(); itr++)
        context += *itr;

      err_oss << "Error #" << error_num << std::endl
              << "  context: " << context << std::endl
              << "  desc:    " << error.description << std::endl;
      ++error_num;
    }
    throw std::runtime_error(err_oss.str());
  }
}

1
我同意这似乎是一个有前途的选择,但现在并不清楚这个库是否还得到支持。 - ddavella
1
自从您发布了这个答案,Boost现在似乎是一个可选的依赖项:https://github.com/tristanpenman/valijson#dependencies。看起来这个变化发生在2019年8月左右:https://github.com/tristanpenman/valijson/issues/63。@ansgri,您的建议超前了时代 :) - GeminiDakota

2
你可以尝试UniversalContainer(libuc)。http://www.greatpanic.com/code.html。你在这个库中寻找容器合同/模式检查类。模式格式比较笨重,但应该能处理你关心的所有内容,并提供有关为什么特定实例未能符合模式的合理报告。

1
有没有一个稳定的库可以根据模式验证JSON? Rapidjson 我正在使用它来验证JSON是否符合模式(大多数情况下)。它似乎经过了测试并且很稳定(根据github存储库,v1.1.0似乎是最新版本)。

这是最好的答案。同时,也是最好的JSON解析器/生成器。 - Tarod

0

0
在Windows平台上,无论您选择哪种语言,都可以使用JSON Essentials for COM/ActiveX。如果您想要在C++中使用MSVC编译器,则可以使用#import预处理器指令生成编译器包装器。
其文档包含大量示例,适用于C#,VB和JavaScript的最常见用例。语言语法是唯一变化的事情,几乎可以在支持COM的任何语言中使用相同的库调用来实现。
值得一提的是,它还提供了免费的许可选项。

Here is a sample of creating a schema, loading and validating a JSON document using the newly created schema for Windows Script Host (WSH) using JSON Essentials evaluation version:

// Create a new JsonEssentials class instance.
var jess = new ActiveXObject('JsonEssentials_0.JsonEssentials.1');
jess.unlock('jesscomeval');

// Create schema JSON document object.
var schemaDoc = jess.createDocument();

// Load JSON schema.
schemaDoc.load({
    'type': 'array',
    'items': {
        'type': 'integer'
    }
});

// Create schema collection object.
var schemas = jess.createSchemas();

// Add the test schema to the collection.
var schema = schemas.add(schemaDoc, 'uri:test');

// Create JSON document object.
var instanceDoc = jess.createDocument();

// Load JSON, an array of numeric values.
instanceDoc.load([ 0, 1, 2 ]);
 
// Validate the test JSON against the added schema.
var status = schema.validate(instanceDoc);

WScript.Echo(status.success ? 'validated' : 'validation failed');


0

你可以查看这个方法https://epub.jku.at/obvulioa/content/pageview/6390647?query=berardinelli

你的JSON文档(元模式、模式或模式实例)的内存表示是使用EMF(Eclipse建模框架)提供的。一旦你有了这个内存表示(保留通常的JSON文本表示法,因此与你现在使用的任何JSON工具兼容),你就可以使用基于EMF的技术,如OCL,以及基于MDE的平台,如Eclipse Epsilon。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接