func setupSchemaLoaders() error { if schema != nil { return nil } var schemaRaw interface{} err := json.Unmarshal([]byte(schemaString), &schemaRaw) if err != nil { return err } schema = schemaRaw.(map[string]interface{}) gojsonschema.FormatCheckers.Add("environment", environmentFormatChecker{}) gojsonschema.FormatCheckers.Add("ports", portsFormatChecker{}) gojsonschema.FormatCheckers.Add("expose", portsFormatChecker{}) schemaLoader = gojsonschema.NewGoLoader(schemaRaw) definitions := schema["definitions"].(map[string]interface{}) constraints := definitions["constraints"].(map[string]interface{}) service := constraints["service"].(map[string]interface{}) constraintSchemaLoader = gojsonschema.NewGoLoader(service) return nil }
func (t *Test) evaluateBody() { if !t.Response.BodyCheck { return } if t.Response.BodyString != "" { b := []byte(t.Response.BodyString) if bytes.Equal(t.Response.body, b) { return } t.fail(fmt.Errorf("expect response body to equal %q, given %q", t.Response.BodyString, t.Response.body)) } else if t.Response.BodyJsonSchema != nil { var v interface{} if err := json.Unmarshal(t.Response.body, &v); err != nil { t.fail(fmt.Errorf("response json body error %s", err)) return } result, err := gojsonschema.Validate(gojsonschema.NewGoLoader(t.Response.BodyJsonSchema), gojsonschema.NewGoLoader(v)) if err != nil { t.fail(fmt.Errorf("validation error %s", err)) return } if !result.Valid() { for _, desc := range result.Errors() { t.fail(fmt.Errorf("JSON schema expect %s", desc)) } } } }
func TestGenJsonSchema(t *testing.T) { str := ` { "k1":"a", "k2":1, "k3":[], "k4":["a"], "k5":[1], "k6":[1.1], "k7":{}, "k8":{"a":1}, "k9":{"a":1,"b":[]}, "k10":{"a":1,"b":[],"c":{"d":1.1}}, "k11":{"a":1,"b":[],"c":{"d":1.1,"f":["a"]}}, "k12":{"a":1,"b":[{"a":1,"b":[1]}]} } ` var obj interface{} err := json.Unmarshal([]byte(str), &obj) assert.Equal(t, err, nil) schema, err := GenJsonSchema(obj) assert.Equal(t, err, nil) _, err = json.MarshalIndent(schema, "", " ") assert.Equal(t, err, nil) // fmt.Println(string(bs)) goSchema, err := gojsonschema.NewSchema(gojsonschema.NewGoLoader(schema)) assert.Equal(t, err, nil) documentLoader := gojsonschema.NewStringLoader(str) ret, err := goSchema.Validate(documentLoader) assert.Equal(t, err, nil) assert.Equal(t, ret.Valid(), true) }
//Validate validates json object using jsoncschema func (schema *Schema) Validate(jsonSchema interface{}, object interface{}) error { schemaLoader := gojsonschema.NewGoLoader(jsonSchema) documentLoader := gojsonschema.NewGoLoader(object) result, err := gojsonschema.Validate(schemaLoader, documentLoader) if err != nil { return err } if result.Valid() { return nil } errDescription := "Json validation error:" for _, err := range result.Errors() { errDescription += fmt.Sprintf("\n\t%v,", err) } return fmt.Errorf(errDescription) }
func (self *Route) validate(params interface{}, version int) (string, error) { route := self.Versions[version] if route == nil { return "", fmt.Errorf("Route version %v missing from %v route", version, self.Name) } if route.Schema == nil { return "", nil } documentLoader := gojsonschema.NewGoLoader(params) result, err := route.Schema.Validate(documentLoader) if err != nil { return "", err } if !result.Valid() { errors := make(map[string]string) for _, resultErr := range result.Errors() { errors[resultErr.Field()] = resultErr.Description() } errorsJson, err := json.Marshal(errors) if err != nil { return "", err } return string(errorsJson), nil } return "", nil }
func validateServiceConstraintsv2(service RawService, serviceName string) error { if err := setupSchemaLoaders(servicesSchemaDataV2, &schemaV2, &schemaLoaderV2, &constraintSchemaLoaderV2); err != nil { return err } service = convertServiceKeysToStrings(service) var validationErrors []string dataLoader := gojsonschema.NewGoLoader(service) result, err := gojsonschema.Validate(constraintSchemaLoaderV2, dataLoader) if err != nil { return err } if !result.Valid() { for _, err := range result.Errors() { if err.Type() == "required" { _, containsImage := service["image"] _, containsBuild := service["build"] if containsBuild || !containsImage && !containsBuild { validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' has neither an image nor a build context specified. At least one must be provided.", serviceName)) } } } return fmt.Errorf(strings.Join(validationErrors, "\n")) } return nil }
func FixDataWithSchema(data interface{}, schema interface{}) (dataFix interface{}, err error) { _, err = gojsonschema.NewSchema(gojsonschema.NewGoLoader(schema)) if err != nil { return nil, err } return fixDataWithSchemaInterface(data, schema) }
// ProcessObject checks if the object is valid from this schema's standpoint // and returns an object with defaults set up according to schema's spec func (j *JSONSchema) ProcessObject(in interface{}) (interface{}, error) { result, err := j.schema.Validate(gojsonschema.NewGoLoader(in)) if err != nil { return nil, trace.Wrap(err) } if !result.Valid() { return nil, trace.Wrap(trace.Errorf("errors: %v", schemaErrors(result.Errors()))) } return setDefaults(j.rawSchema, in), nil }
func checkSchema(chain *chain, value, schema interface{}) { if chain.failed() { return } valueLoader := gojsonschema.NewGoLoader(value) var schemaLoader gojsonschema.JSONLoader if str, ok := toString(schema); ok { if ok, _ := regexp.MatchString(`^\w+://`, str); ok { schemaLoader = gojsonschema.NewReferenceLoader(str) } else { schemaLoader = gojsonschema.NewStringLoader(str) } } else { schemaLoader = gojsonschema.NewGoLoader(schema) } result, err := gojsonschema.Validate(schemaLoader, valueLoader) if err != nil { chain.fail("\n%s\n\nschema:\n%s\n\nvalue:\n%s", err.Error(), dumpSchema(schema), dumpValue(value)) return } if !result.Valid() { errors := "" for _, err := range result.Errors() { errors += fmt.Sprintf(" %s\n", err) } chain.fail( "\njson schema validation failed, schema:\n%s\n\nvalue:%s\n\nerrors:\n%s", dumpSchema(schema), dumpValue(value), errors) return } }
// ValidateJSON validates the given runtime against its defined schema func (cfg *RuntimeOptions) ValidateJSON() error { schema := gojson.NewStringLoader(RuntimeSchema) doc := gojson.NewGoLoader(cfg) if result, err := gojson.Validate(schema, doc); err != nil { return err } else if !result.Valid() { return combineErrors(result.Errors()) } return nil }
func (s *JSONSchema) getSchema() (schema *gojsonschema.Schema, err error) { if s.schema != nil && !s.enumLoader.IsDirty() { return s.schema, nil } loader := gojsonschema.NewGoLoader(s.GetPreprocessed()) s.schema, err = gojsonschema.NewSchema(loader) if err != nil { return } return s.schema, nil }
func (c *InterfaceController) Update(w http.ResponseWriter, r *http.Request) { // Get ID id := mux.Vars(r)["id"] // Validate ObjectId if !bson.IsObjectIdHex(id) { w.WriteHeader(http.StatusNotFound) return } // Get object id oid := bson.ObjectIdHex(id) // Initialize empty struct s := models.Interface{} // Decode JSON into struct err := json.NewDecoder(r.Body).Decode(&s) if err != nil { jsonError(w, r, "Failed to deconde JSON: "+err.Error(), http.StatusInternalServerError, c.envelope) return } // Validate input using JSON Schema docLoader := gojsonschema.NewGoLoader(s) schemaLoader := gojsonschema.NewReferenceLoader(c.schemaURI) res, err := gojsonschema.Validate(schemaLoader, docLoader) if err != nil { jsonError(w, r, "Failed to load schema: "+err.Error(), http.StatusInternalServerError, c.envelope) return } if !res.Valid() { var errors []string for _, e := range res.Errors() { errors = append(errors, fmt.Sprintf("%s: %s", e.Context().String(), e.Description())) } jsonError(w, r, errors, http.StatusInternalServerError, c.envelope) return } // Update entry if err := c.session.DB(c.database).C("interfaces").UpdateId(oid, s); err != nil { jsonError(w, r, err.Error(), http.StatusInternalServerError, c.envelope) return } // Write content-type, header and payload jsonWriter(w, r, s, http.StatusOK, c.envelope) }
func (s schema) Validate(data interface{}) error { result, _ := s.schema.Validate(gojsonschema.NewGoLoader(data)) if result.Valid() { return nil } msgs := []string{} for _, e := range result.Errors() { msgs = append(msgs, e.Description()) } return singleIssue("", "Faild to validate sub-schema at {path}, errors: %s", strings.Join(msgs, ", "), ) }
// New returns JSON schema created from JSON byte string // returns a valid schema or error if schema is invalid func New(data []byte) (*JSONSchema, error) { j := JSONSchema{} err := json.Unmarshal(data, &j.rawSchema) if err != nil { return nil, trace.Wrap(err) } loader := gojsonschema.NewGoLoader(j.rawSchema) j.schema, err = gojsonschema.NewSchema(loader) if err != nil { return nil, trace.Wrap(err) } return &j, nil }
// validateRequestData takes in a schema path and the request // and will do the legwork of determining if the post data is valid func validateRequestData(schemaPath string, r *web.Request) ( document map[string]interface{}, result *gojsonschema.Result, err error, ) { err = json.NewDecoder(r.Body).Decode(&document) if err == nil && schemaPath != "" { schemaLoader := gojsonschema.NewReferenceLoader(schemaPath) documentLoader := gojsonschema.NewGoLoader(document) result, err = gojsonschema.Validate(schemaLoader, documentLoader) } return document, result, err }
func validateJSON(schema string, obj Entity) error { schemaObj := gojson.NewStringLoader(schema) doc := gojson.NewGoLoader(obj) if result, err := gojson.Validate(schemaObj, doc); err != nil { return err } else if !result.Valid() { var errors []string for _, err := range result.Errors() { errors = append(errors, fmt.Sprintf("%s\n", err)) } return errored.New(strings.Join(errors, "\n")) } return nil }
func validateV2(serviceMap RawServiceMap) error { if err := setupSchemaLoaders(servicesSchemaDataV2, &schemaV2, &schemaLoaderV2, &constraintSchemaLoaderV2); err != nil { return err } serviceMap = convertServiceMapKeysToStrings(serviceMap) dataLoader := gojsonschema.NewGoLoader(serviceMap) result, err := gojsonschema.Validate(schemaLoaderV2, dataLoader) if err != nil { return err } return generateErrorMessages(serviceMap, schemaV2, result) }
// ProcessObject checks if the object is valid from this schema's standpoint // and returns an object with defaults set up according to schema's spec func (j *JSONSchema) ProcessObject(in interface{}) (interface{}, error) { defaults := setDefaults(j.rawSchema, in) result, err := j.schema.Validate(gojsonschema.NewGoLoader(defaults)) if err != nil { return nil, trace.Wrap(err) } if !result.Valid() { errors := result.Errors() output := make([]string, len(errors)) for i, err := range errors { output[i] = fmt.Sprintf("%v", err) } return nil, trace.Errorf("failed to validate: %v", strings.Join(output, ",")) } return defaults, nil }
func validateFunc(e Etcdtool, dir string, d interface{}) { // Map directory to routes. var schema string for _, r := range e.Routes { match, err := regexp.MatchString(r.Regexp, dir) if err != nil { fatal(err.Error()) } if match { schema = r.Schema } } if schema == "" { fatal("Couldn't determine which JSON schema to use for validation") } /* if schema == "" && len(c.Args()) == 1 { fatal("You need to specify JSON schema URI") } if len(c.Args()) > 1 { schema = c.Args()[1] } */ // Validate directory. infof("Using JSON schema: %s", schema) schemaLoader := gojsonschema.NewReferenceLoader(schema) docLoader := gojsonschema.NewGoLoader(d) result, err := gojsonschema.Validate(schemaLoader, docLoader) if err != nil { fatal(err.Error()) } // Print results. if !result.Valid() { for _, err := range result.Errors() { fmt.Printf("%s: %s\n", strings.Replace(err.Context().String("/"), "(root)", dir, 1), err.Description()) } fatal("Data validation failed aborting") } }
func (c *TenantController) Create(w http.ResponseWriter, r *http.Request) { // Initialize empty struct s := models.Tenant{} // Decode JSON into struct err := json.NewDecoder(r.Body).Decode(&s) if err != nil { jsonError(w, r, "Failed to deconde JSON: "+err.Error(), http.StatusInternalServerError, c.envelope) return } // Set ID s.ID = bson.NewObjectId() // Validate input using JSON Schema log.Printf("Using schema: %s", c.schemaURI) docLoader := gojsonschema.NewGoLoader(s) schemaLoader := gojsonschema.NewReferenceLoader(c.schemaURI) res, err := gojsonschema.Validate(schemaLoader, docLoader) if err != nil { jsonError(w, r, err.Error(), http.StatusInternalServerError, c.envelope) return } if !res.Valid() { var errors []string for _, e := range res.Errors() { errors = append(errors, fmt.Sprintf("%s: %s", e.Context().String(), e.Description())) } jsonError(w, r, errors, http.StatusInternalServerError, c.envelope) return } // Insert entry if err := c.session.DB(c.database).C("tenants").Insert(s); err != nil { jsonError(w, r, err.Error(), http.StatusInternalServerError, c.envelope) return } // Write content-type, header and payload jsonWriter(w, r, s, http.StatusCreated, c.envelope) }
// Validate uses the jsonschema to validate the configuration func Validate(config map[string]interface{}) error { schemaData, err := Asset("data/config_schema_v3.0.json") if err != nil { return err } schemaLoader := gojsonschema.NewStringLoader(string(schemaData)) dataLoader := gojsonschema.NewGoLoader(config) result, err := gojsonschema.Validate(schemaLoader, dataLoader) if err != nil { return err } if !result.Valid() { return toError(result) } return nil }
/** * Function validates JSON schema for `device` od `channel` models * By convention, Schema files must be kept as: * - ./models/deviceSchema.json * - ./models/channelSchema.json */ func validateJsonSchema(model string, body map[string]interface{}) bool { pwd, _ := os.Getwd() schemaLoader := gojsonschema.NewReferenceLoader("file://" + pwd + "/schema/" + model + "Schema.json") bodyLoader := gojsonschema.NewGoLoader(body) result, err := gojsonschema.Validate(schemaLoader, bodyLoader) if err != nil { log.Print(err.Error()) } if result.Valid() { fmt.Printf("The document is valid\n") return true } else { fmt.Printf("The document is not valid. See errors :\n") for _, desc := range result.Errors() { fmt.Printf("- %s\n", desc) } return false } }
// NewSchema creates a Schema that wraps a jsonschema. // The jsonschema can be specified as a JSON string or a hierarchy of // * map[string]interface{} // * []interface{} // * string // * float64 // * bool // * nil func NewSchema(jsonschema interface{}) (Schema, error) { var loader gojsonschema.JSONLoader if s, ok := jsonschema.(string); ok { var target interface{} if err := json.Unmarshal([]byte(s), &target); err != nil { return nil, fmt.Errorf("Failed to parse JSON string, error: %s", err) } jsonschema = target } obj, ok := jsonschema.(map[string]interface{}) if !ok { return nil, fmt.Errorf("Expected map[string]interface{} got: %T", jsonschema) } loader = gojsonschema.NewGoLoader(jsonschema) s, err := gojsonschema.NewSchema(loader) if err != nil { return nil, err } return schema{schema: s, raw: obj}, nil }
func (self *Route) validate(params map[string]interface{}) (string, error) { if self.Schema == nil { return "", nil } documentLoader := gojsonschema.NewGoLoader(params) result, err := self.Schema.Validate(documentLoader) if err != nil { return "", err } if !result.Valid() { errors := make(map[string]string) for _, resultErr := range result.Errors() { errors[resultErr.Field()] = resultErr.Description() } errorsJson, err := json.Marshal(errors) if err != nil { return "", err } return string(errorsJson), nil } return "", nil }
func validateServiceConstraints(service RawService, serviceName string) error { if err := setupSchemaLoaders(); err != nil { return err } service = convertServiceKeysToStrings(service) var validationErrors []string dataLoader := gojsonschema.NewGoLoader(service) result, err := gojsonschema.Validate(constraintSchemaLoader, dataLoader) if err != nil { return err } if !result.Valid() { for _, err := range result.Errors() { if err.Type() == "number_any_of" { _, containsImage := service["image"] _, containsBuild := service["build"] _, containsDockerfile := service["dockerfile"] if containsImage && containsBuild { validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' has both an image and build path specified. A service can either be built to image or use an existing image, not both.", serviceName)) } else if !containsImage && !containsBuild { validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' has neither an image nor a build path specified. Exactly one must be provided.", serviceName)) } else if containsImage && containsDockerfile { validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' has both an image and alternate Dockerfile. A service can either be built to image or use an existing image, not both.", serviceName)) } } } return fmt.Errorf(strings.Join(validationErrors, "\n")) } return nil }
// Validation rules: // Grammar expr is: // String that starts with $ -> Look for type match // String (without $) -> Exact match // Object -> Treat object as a JSON schema and validate input with it // Otherwise -> No match func matchExpr(input *simplejson.Json, grammar *simplejson.Json, diag bool) bool { if grammar == nil && input == nil { return true } if grammar == nil || input == nil { if diag { log.Printf("Grammar was %v while input was %v", grammar, nil) } return false } stype, err := grammar.String() if err == nil { switch stype { case "$_": return true case "$string": _, terr := input.String() if terr != nil && diag { log.Printf("Input wasn't a string") } return terr == nil case "$bool": _, terr := input.Bool() if terr != nil && diag { log.Printf("Input wasn't a bool") } return terr == nil case "$int": _, terr := input.Int64() if terr != nil && diag { log.Printf("Input wasn't an int") } return terr == nil case "$number": _, terr := input.Float64() if terr != nil && diag { log.Printf("Input wasn't a number") } return terr == nil default: is, terr := input.String() log.Printf("treated as literal") return terr == nil && is == stype } } mtype, err := grammar.Map() if err == nil { schemaLoader := gojsonschema.NewGoLoader(mtype) documentLoader := gojsonschema.NewGoLoader(input) result, err := gojsonschema.Validate(schemaLoader, documentLoader) if err != nil { log.Printf("Validation error: %v", err) return false } for _, e := range result.Errors() { log.Printf(" JSON Schema validation failed because: %s", e) } return result.Valid() } return false }
func (v *UserValidater) Validate(u *User) (error, []string) { dl := gojsonschema.NewGoLoader(u) return validate(v.sl, dl) }
func validate(serviceMap RawServiceMap) error { if err := setupSchemaLoaders(); err != nil { return err } serviceMap = convertServiceMapKeysToStrings(serviceMap) var validationErrors []string dataLoader := gojsonschema.NewGoLoader(serviceMap) result, err := gojsonschema.Validate(schemaLoader, dataLoader) if err != nil { return err } // gojsonschema can create extraneous "additional_property_not_allowed" errors in some cases // If this is set, and the error is at root level, skip over that error skipRootAdditionalPropertyError := false if !result.Valid() { for i := 0; i < len(result.Errors()); i++ { err := result.Errors()[i] if skipRootAdditionalPropertyError && err.Type() == "additional_property_not_allowed" && err.Context().String() == "(root)" { skipRootAdditionalPropertyError = false continue } if err.Context().String() == "(root)" { switch err.Type() { case "additional_property_not_allowed": validationErrors = append(validationErrors, fmt.Sprintf("Invalid service name '%s' - only [a-zA-Z0-9\\._\\-] characters are allowed", err.Field())) default: validationErrors = append(validationErrors, err.Description()) } } else { skipRootAdditionalPropertyError = true serviceName := serviceNameFromErrorField(err.Field()) key := keyNameFromErrorField(err.Field()) switch err.Type() { case "additional_property_not_allowed": validationErrors = append(validationErrors, unsupportedConfigMessage(key, result.Errors()[i+1])) case "number_one_of": validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' configuration key '%s' %s", serviceName, key, oneOfMessage(serviceMap, schema, err, result.Errors()[i+1]))) // Next error handled in oneOfMessage, skip over it i++ case "invalid_type": validationErrors = append(validationErrors, invalidTypeMessage(serviceName, key, err)) case "required": validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' option '%s' is invalid, %s", serviceName, key, err.Description())) case "missing_dependency": dependency := err.Details()["dependency"].(string) validationErrors = append(validationErrors, fmt.Sprintf("Invalid configuration for '%s' service: dependency '%s' is not satisfied", serviceName, dependency)) case "unique": contextWithDuplicates := getValue(serviceMap, err.Context().String()) validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' configuration key '%s' value %s has non-unique elements", serviceName, key, contextWithDuplicates)) default: validationErrors = append(validationErrors, fmt.Sprintf("Service '%s' configuration key %s value %s", serviceName, key, err.Description())) } } } return fmt.Errorf(strings.Join(validationErrors, "\n")) } return nil }
func Validate(stackName string, filePath string) error { stack := Stack{Name: ""} data, err := ioutil.ReadFile(filePath) if err != nil { return err } yaml.Unmarshal(data, &stack.Definition) nameLoader := gojsonschema.NewStringLoader(NAME_SCHEMA) schemaLoader := gojsonschema.NewStringLoader(SERVICE_SCHEMA) documentLoader := gojsonschema.NewGoLoader(stackName) result, err := gojsonschema.Validate(nameLoader, documentLoader) if err != nil { return err } if !result.Valid() { message := "Stack name not valid: " for _, desc := range result.Errors() { message += fmt.Sprintf("'%s' %s\n", desc.Value, desc.Description) } return errors.New(message) } stack.SetDefaults() for name, definition := range stack.Definition { documentLoader := gojsonschema.NewGoLoader(name) result, err := gojsonschema.Validate(nameLoader, documentLoader) if err != nil { return err } if !result.Valid() { var message string message = "Service name not valid: " for _, desc := range result.Errors() { message += fmt.Sprintf("'%s' %s\n", desc.Value, desc.Description) } return errors.New(message) } documentLoader = gojsonschema.NewGoLoader(definition) result, err = gojsonschema.Validate(schemaLoader, documentLoader) if err != nil { return err } if !result.Valid() { var message string message = "Service " + name + " not valid. see errors:\n" for _, desc := range result.Errors() { message += fmt.Sprintf("%s: '%s' %s\n", desc.Context.String()[7:], desc.Value, desc.Description) } return errors.New(message) } for _, link := range definition.Links { linkAndAlias := strings.Split(link, ":") var linkedService string if len(linkAndAlias) == 2 { linkedService = linkAndAlias[1] } else { linkedService = linkAndAlias[0] } _, ok := stack.Definition[linkedService] if !ok { return fmt.Errorf("Linked service '%s' in service '%s' does not exist\n", linkedService, name) } } for _, volumesFrom := range definition.Volumes_from { _, ok := stack.Definition[volumesFrom] if !ok { return fmt.Errorf("VolumesFrom '%s' in service '%s' does not exist\n", volumesFrom, name) } } } return nil }
// validateCommandFunc validate data using JSON Schema. func validateCommandFunc(c *cli.Context) { if len(c.Args()) == 0 { fatal("You need to specify directory") } dir := c.Args()[0] // Remove trailing slash. if dir != "/" { dir = strings.TrimRight(dir, "/") } infof("Using dir: %s", dir) // Load configuration file. e := loadConfig(c) // New dir API. ki := newKeyAPI(e) // Map directory to routes. var schema string for _, r := range e.Routes { match, err := regexp.MatchString(r.Regexp, dir) if err != nil { fatal(err.Error()) } if match { schema = r.Schema } } if schema == "" && len(c.Args()) == 1 { fatal("You need to specify JSON schema URI") } if len(c.Args()) > 1 { schema = c.Args()[1] } // Get directory. ctx, cancel := contextWithCommandTimeout(c) resp, err := ki.Get(ctx, dir, &client.GetOptions{Recursive: true}) cancel() if err != nil { fatal(err.Error()) } m := etcdmap.Map(resp.Node) // Validate directory. infof("Using JSON schema: %s", schema) schemaLoader := gojsonschema.NewReferenceLoader(schema) docLoader := gojsonschema.NewGoLoader(m) result, err := gojsonschema.Validate(schemaLoader, docLoader) if err != nil { fatal(err.Error()) } // Print results. if !result.Valid() { for _, err := range result.Errors() { fmt.Printf("%s: %s\n", strings.Replace(err.Context().String("/"), "(root)", dir, 1), err.Description()) } } }