2011-01-13 8 views
22

Gibt es eine stabile Bibliothek, die JSON gegen eine schema validieren kann?JSON-Schema-Validierung

json-schema.org bietet eine list of implementations. Bemerkenswerterweise fehlen C und C++.

Gibt es einen Grund, warum ich einen C++ - JSON-Schema-Validator nicht einfach finden kann?
Will sonst niemand eine schnelle Möglichkeit, eingehende JSON-Dateien zu validieren?

+3

Wahrscheinlich weil C und C++ sind selten für Webapps verwendet, die die vorherrschende Anwendung von JSON ist. Wenn es keine gibt, könnten Sie eine andere nehmen und sie portieren. –

+3

JSON kann (ist?) Für viel mehr verwendet werden, als zwischen Browsern und Webservern zu sprechen. Vielleicht möchten Sie es speichern Präferenzen, RPC zwischen Systemen, etc. Grundsätzlich überall wo xml heute verwendet wird. –

+2

@Mark: Das ist tatsächlich unser genauer Anwendungsfall. Wir brauchen eine Möglichkeit, komplexe Konfigurationen zu speichern (zu komplex für ini). Wir haben JSON als über XML ausgewählt. –

Antwort

18

Gibt es eine stabile Bibliothek, die JSON gegen ein Schema validieren kann?

fand ich ein paar Treffer auf Google:

Sie auch ein Python oder Javascript-Interpreter in Ihre App stecken könnte, und Führen Sie einfach die native Version derjenigen Validator-Implementierungen aus, die Sie bereits gefunden haben.

Gibt es einen Grund, warum ich nicht einfach einen C++ JSON-Schema-Validator finden kann?

Ich glaube, dass JSON als Web-Technologie entstanden ist, und C/C++ ist für die Web-App-Implementierung in Ungnade gefallen.

+6

+1 für "... gefallen in Ungnade ..." –

+1

Der Chromium-Validator sieht wirklich aus Gut, aber ich möchte das Schema aus dem Basiscode des Chroms extrahieren, bevor ich es benutze. Es ist also kein Tropfen in der Lösung, aber viel besser als selbst einen zu schreiben. –

+0

Die [JSON-Schemasite] (http://json-schema.org/implementations.html) listet eine C-Bibliothek (WJElement) auf, aber ich habe keine Erfahrung damit, und ich bin mir ziemlich sicher, dass es nicht funktioniert. t unterstützt die neueste Version des Standards. – cloudfeet

2

Sie können UniversalContainer (libuc) versuchen. http://www.greatpanic.com/code.html. Sie suchen in dieser Bibliothek nach der Containerklasse/Schemakontrollklasse. Das Schema-Format ist klobig, sollte aber alles behandeln, was Ihnen wichtig ist, und vernünftige Berichte darüber liefern, warum eine bestimmte Instanz das Schema nicht erfüllt.

2

Valijson ist eine sehr gute Bibliothek, die nur von Boost abhängt (Und ich hoffe eigentlich auf change dass). Es hängt nicht einmal von einem bestimmten JSON-Parser ab, der Adapter für die am häufigsten verwendeten Bibliotheken wie JsonCpp, Rapidjson und Json11 bereitstellt.

Der Code kann die ausführliche erscheinen, aber man kann immer einen Helfer (Beispiel für JsonCpp) schreiben:

#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()); 
    } 
}