Validation de schéma JSON
Existe-t-il une bibliothèque stable qui peut valider JSON par rapport à un schéma ?
Json-schema.org fournit un liste des implémentations. Notamment C et c++ sont manquants.
Y a-t-il une raison pour laquelle je ne peux pas facilement trouver un validateur de schéma JSON C++?
Personne d'autre ne veut-il un moyen rapide de valider les fichiers JSON entrants?
3 réponses
Existe-t-il une bibliothèque stable qui peut valider JSON par rapport à un schéma?
J'ai trouvé quelques hits sur google:
- du projet Chromium: 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
Vous pouvez également brancher un interpréteur Python ou Javascript dans votre application, et simplement exécuter la version native de ces validateurs implémentations que vous avez déjà trouvées.
Y a-t-il une raison pour laquelle je ne peux pas facilement trouver un validateur de schéma JSON C++?
Je crois que JSON est né comme une technologie web, et C / c++ est tombé en disgrâce pour la mise en œuvre de l'application web.
Valijson est une très bonne bibliothèque qui ne dépend que de Boost (et j'espère en fait changer cela). Il ne dépend même pas d'un analyseur JSON particulier, fournissant des adaptateurs pour les bibliothèques les plus couramment utilisées comme JsonCpp, rapidjson et json11.
Le code peut sembler verbeux, mais vous pouvez toujours écrire un assistant (exemple pour 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());
}
}
Vous pouvez essayer UniversalContainer (libuc). http://www.greatpanic.com/code.html . Vous recherchez la classe container contract/schema checking dans cette bibliothèque. Le format de schéma est maladroit, mais devrait gérer tout ce qui vous intéresse et fournir des rapports raisonnables sur les raisons pour lesquelles une instance particulière ne répond pas au schéma.