JSON schema validation
Is there a stable library that can validate JSON against a schema?
I found a couple hits on google:
- From the Chromium project: http://aaronboodman-com-v1.blogspot.com/2010/11/c-version-of-json-schema.html
- http://avro.apache.org/docs/1.4.1/api/cpp/html/index.html
You could also plug a Python or Javascript interpreter into your app, and simply run the native version of those validator implementations that you've already found.
Is there a reason I can't easily find a C++ JSON schema validator?
I believe JSON originated as a web technology, and C/C++ has fallen out of favor for web app implementation.
Valijson is a very good library which depends only on Boost (And I'm actually hoping to change that). It doesn't even depend on any particular JSON parser, providing adapters for most commonly-used libraries like JsonCpp, rapidjson and json11.
The code may seem verbose, but you can always write a helper (example for 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()); }}
You can try UniversalContainer (libuc). http://www.greatpanic.com/code.html. You're looking for the container contract/schema checking class in this library. The schema format is clunky, but should handle everything you care about and provide reasonable reporting on why a particular instance fails to meet the schema.