2011-01-13 20 views
22

¿Existe una biblioteca estable que pueda validar JSON con un schema?Validación de esquema JSON

json-schema.org proporciona un list of implementations. Notablemente faltan C y C++.

¿Hay algún motivo por el que no pueda encontrar fácilmente un validador de esquema C++ JSON?
¿Alguien más quiere una forma rápida de validar los archivos JSON entrantes?

+3

Lo más probable debido a que C y C++ rara vez se utilizan para aplicaciones web, que es la aplicación predominante de JSON. Si no hay ninguno, podría tomar otro y portarlo. –

+3

JSON puede (¿es?) Utilizarse para mucho más que hablar entre navegadores y servidores web. Es posible que desee usarlo almacenando preferencias, RPC entre sistemas, etc. Básicamente, cualquier lugar xml se usa (incorrectamente) en la actualidad. –

+2

@Mark: de hecho, este es nuestro caso de uso exacto. Necesitamos una forma de almacenar una configuración compleja (demasiado compleja para ini). Elegimos JSON como más de xml. –

Respuesta

18

¿Existe una biblioteca estable que pueda validar JSON con un esquema?

me encontré con un par de golpes en Google:

También puede conectar un intérprete de Python o JavaScript en su aplicación, y simplemente ejecute la versión nativa de las implementaciones de validación que ya ha encontrado.

¿Hay algún motivo por el que no pueda encontrar fácilmente un validador de esquemas C++ JSON?

Creo que JSON se originó como una tecnología web, y C/C++ ha caído en desgracia para la implementación de aplicaciones web.

+6

+1 para "... caído en desgracia ..." –

+1

El validador de Chromium se ve realmente bien, pero me gustaría extraer el esquema del código base del cromo antes de usarlo. Por lo tanto, no es una solución, sino mucho mejor que escribir uno yo mismo. –

+0

El [sitio de esquema JSON] (http://json-schema.org/implementations.html) enumera una biblioteca C (WJElement), pero no tengo ninguna experiencia con él, y estoy bastante seguro de que no es así. t admite la última versión del estándar. – cloudfeet

2

Puede intentar UniversalContainer (libuc). http://www.greatpanic.com/code.html. Está buscando la clase de control de contrato/esquema de contenedor en esta biblioteca. El formato del esquema es torpe, pero debe manejar todo lo que le interesa y proporcionar informes razonables sobre por qué una instancia en particular no cumple con el esquema.

2

Valijson es una muy buena biblioteca que depende solo de Boost (y realmente espero change eso). Ni siquiera depende de ningún analizador JSON en particular, ya que proporciona adaptadores para las bibliotecas más utilizadas, como JsonCpp, rapidjson y json11.

El código puede parecer prolijo, pero siempre se puede escribir un ayudante (ejemplo para 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()); 
    } 
} 
Cuestiones relacionadas