2011-01-13 15 views
22

Esiste una libreria stabile in grado di convalidare JSON rispetto a schema?Convalida dello schema JSON

json-schema.org fornisce un list of implementations. In particolare mancano C e C++.

C'è un motivo per cui non riesco a trovare facilmente un validatore di schema JSON C++?
Qualcun altro desidera un modo rapido per convalidare i file JSON in arrivo?

+3

molto probabilmente perché C e C++ sono raramente utilizzate per webapps, che è l'applicazione predominante di JSON. Se non ce ne sono, puoi prenderne un altro e portarlo. –

+3

JSON può (è?) Utilizzato per molto più che parlare tra browser e server web. Potresti volerlo usare per memorizzare le preferenze, RPC tra i sistemi, ecc. Fondamentalmente, ovunque xml è (errato) usato oggi. –

+2

@ Mark: effettivamente questo è il nostro caso d'uso esatto. Abbiamo bisogno di un modo per archiviare una configurazione complessa (troppo complessa per ini). Abbiamo scelto JSON come oltre xml. –

risposta

18

Esiste una libreria stabile in grado di convalidare JSON rispetto a uno schema?

ho trovato un paio di visite su Google:

Si potrebbe anche collegare un interprete Python o JavaScript nella vostra applicazione, e semplicemente esegui la versione nativa di quelle implementazioni di validatori che hai già trovato.

C'è un motivo per cui non riesco a trovare facilmente un validatore di schema JSON C++?

Credo che JSON sia nato come tecnologia web e C/C++ è caduto in disgrazia per l'implementazione della web app.

+6

+1 per "... caduto in disgrazia ..." –

+1

Il validatore Chromium sembra davvero buono ma vorrei estrarre lo schema dal codice base del cromo prima di usarlo. Quindi non è una soluzione, ma molto meglio che scriverne uno io stesso. –

+0

Il [sito JSON Schema] (http://json-schema.org/implementations.html) elenca una libreria C (WJElement), ma non ho alcuna esperienza con esso, e sono abbastanza sicuro che non lo faccia t supportare l'ultima versione dello standard. – cloudfeet

2

Puoi provare UniversalContainer (libuc). http://www.greatpanic.com/code.html. Stai cercando la classe di controllo contratto/schema contenitore in questa libreria. Il formato dello schema è goffo, ma dovrebbe gestire tutto ciò che ti interessa e fornire rapporti ragionevoli sul motivo per cui una particolare istanza non riesce a soddisfare lo schema.

2

Valijson è una libreria molto buona che dipende solo da Boost (e in realtà spero di poterlo fare a change). Non dipende nemmeno da alcun particolare parser JSON, fornendo adattatori per le librerie più comuni come JsonCpp, rapidjson e json11.

Il codice può sembrare prolisso, ma si può sempre scrivere un aiutante (esempio per 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()); 
    } 
} 
Problemi correlati