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?

23
demandé sur deft_code 2011-01-13 05:18:59

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:

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.

18
répondu Merlyn Morgan-Graham 2013-04-04 15:04:16

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());
  }
}
3
répondu ansgri 2016-01-30 11:37:00

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.

2
répondu user693653 2012-12-31 18:43:54