I'm using Ajv version 6.10.2 to validate a simple Json schema that is separated in two files, but the thing is that I don't get the errors when doing the validation even though the json that I use to test is wrong.
This are the two parts of the schema:
root.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://test.com/schemas/root.json",
"title": "test",
"description": "test",
"type": "object",
"properties": {
"entrypoint": { "$ref": "entrypoint.json" }
},
"additionalProperties": false,
"required": ["entrypoint"]
}
entrypoint.json
{
"$id": "http://test.com/schemas/entrypoint.json",
"description": "test object",
"type": "string"
}
I instantiate Ajv like this
import Ajv from 'ajv';
import root from './root.json';
import entrypoint from './entrypoint.json';
const ajv = new Ajv({
allErrors: true,
schemas: [
test,
entrypoint,
],
});
This is the validation call
const validate = ajv.getSchema('http://test.com/schemas/root.json');
And this is the json used to test against the schema
{
entrypoint: '',
incorrect: {}
}
It comes out as invalid but it doesn't show no errors, I've been going over it for a long time but I haven't found a reason.
Thanks in advance
Your problem is, you have no schema with the $id of http://test.com/schemas/test.json. You need to pass in the identifier (in your case, the full URI) of the schema you wish to use for validation into getSchema.
I can see you've copied from the documentation the URI shown as an example.
Related
Using MarkLogic version 10.0-4.2, I am trying to validate a simple JSON record against a simple JSON schema.
JSON Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"SourceSystemName": {
"type": "string"
},
"BatchDtTm": {
"type": "string"
},
"SubjectArea": {
"type": "string"
},
"DocumentType": {
"type": "string"
},
"LastUpdatedDt": {
"type": "string"
},
"required": [
"SourceSystemName",
"BatchDtTm",
"SubjectArea",
"DocumentType",
"LastUpdatedDt",
]
}
}
Code being run in Query Console:
let jsonRecord = {"SourceSystemName":"ODH","BatchDtTm":"09/17/21 08:51:48:472723","SubjectArea":"Customer","DocumentType":"Preference","LastUpdatedDt":"09/17/21 03:59:53:629707"};
xdmp.jsonValidate(jsonRecord, cts.doc('/schemas/NewSchema.json').toString());
When I run the above code, I get error
XDMP-JSVALIDATEBADSCHEMA: Invalid schema "": ""
I'm not really sure what is 'invalid' about my schema. Can someone offer some insight into what MarkLogic is viewing as 'invalid'?
The second parameter for $schema is supposed to be the URI of the schema document.
$schema URI of the JSON schema to use for validation.
You are attempting to pass in the stringified content.
Try:
xdmp.jsonValidate(jsonRecord, '/schemas/NewSchema.json');
And ensure that the schema document is inserted into the Schemas database, not the content database.
Good morning,
I have a problem using ajv with a json-schema, when using a $ref to something defined in the same json file. I suspect that the problem is with the use of ids, I would understand more about that.
My files are:
definitions.json
{
"$schema":"http://json-schema.org/draft-06/schema#",
"definitions": {
"person":{
"$schema":"http://json-schema.org/draft-06/schema#",
"$id": "http://asite.org/schemas/person.json",
"type":"object",
"properties": {
"name":{"type":"string"},
"surname":{"type":"string"},
"email": {"type": "string", "format": "email"},
"sex":{"$ref": "types.json#/definitions/gender"}},
"required":["name", "surname", "sex", "email"]
},
"member":{
"$schema":"http://json-schema.org/draft-06/schema#",
"type": "object",
"$id": "http://asite.org/schemas/member.json",
"allOf":[
{"$ref": "#/definitions/person"},
{
"properties": {
"id":{"type":"integer"},
"role":{"$ref": "types.json#/properties/man_role"},
"is_expert":{"type":"boolean", "default":false},
"is_board":{"type":"boolean", "default": false}
}
}
]
}
},
"type":"object",
"properties": {
"person": {"$ref": "#/definitions/person"},
"member": {"$ref": "#/definitions/member"}
}
}
types.json
{
"$schema":"http://json-schema.org/draft-06/schema#",
"$id": "http://asite.org/schemas/types.json",
"type": "object",
"definitions": {
"gender":{"enum": ["male", "female"]},
"man_role":{"enum": ["admin", "supervisor", "clerk", "none"]}
},
"properties":{
"gender":{"$ref": "#/definitions/gender"},
"man_role": {"$ref": "#/definitions/man_role"}
}
}
I looked at this question, but I didn't figure it out how to correct my example.
The error I get is:
MissingRefError: can't resolve reference #/definitions/person from id http://asite.org/schemas/member.json
The references work if I try with VisualStudio Code, e.g I can create a "member" and it recognizes also the properties of "person".
Can anyone tell me how should write these schemas to make them work with ajv?
The code that generates the error is:
import Ajv, {JSONSchemaType, DefinedError} from "ajv"
import {Person, Member} from "./definitions";
import addFormats from "ajv-formats"
const ajv = new Ajv();
addFormats(ajv);
ajv.addMetaSchema(require("../node_modules/ajv/lib/refs/json-schema-draft-06.json"))
const types = require("../types.json");
const PersonSchema : JSONSchemaType<Person> = require('../definitions.json').definitions.person;
const MemberSchema: JSONSchemaType<Member> = require('../definitions.json').definitions.member;
ajv.addSchema(types);
const isPerson = ajv.compile(PersonSchema);
const isMember = ajv.compile(MemberSchema)
//other stuff, use of isPerson and isMember on example objects
Your intuition is correct, the $ref isn't resolving as you expect because of the $id. $refs are resolved against the $id of the schema. In this case, { "$ref": "#/definitions/person" } is resolved against "$id": "http://asite.org/schemas/member.json" resulting in http://asite.org/schemas/member.json#/definitions/person which doesn't exist. The solution is to use the $id of the person schema rather than a relative path: { "$ref": "person.json" }.
As an aside, you might prefer the alternate API for compiling schemas that works better when dealing with bundled schemas like your "definitions.json". You can load the whole file and then compile the individual schemas you want by their $id.
const ajv = new Ajv();
ajv.addMetaSchema(draft06);
ajv.addSchema(definitions);
ajv.addSchema(types);
const isPerson = ajv.getSchema("http://asite.org/schemas/person.json");
const isMember = ajv.getSchema("http://asite.org/schemas/member.json");
BACKGROUND:
I have mockedup my issue here for reference:
https://jsonschemalint.com/#/version/draft-06/markup/json?gist=4c185903d7aeb13f6977852a09cf5462
and I am using this npm package: https://www.npmjs.com/package/jsonschema
CODE
//i read in JSON specified in files (the contents of which are below) and parse them into JSON objects. This process works fine.
var jsonDef = JSON.parse(schemaFile); //i store this jsonDef in my database as an object
var jsonObj = JSON.parse(objFile);
var jsonv = new JSONValidator();
var validateResult = jsonv.validate(jsonObj, jsonDef); //jsonDef is read from my database
//validateResult.valid is true
PROBLEM:
I have a general schema + metadata definition like so ("props" contains the actual object schema I want to validate)
schemaFile:
{
"name":"schoolDemo",
"displayName":"School Demo",
"propertiesKey":"assetId",
"props":{
"assetId": {
"type": "string"
},
"grade": {
"type": "number"
}
}
}
objFile:
{
"assetId": "75255972",
"grade": "A"
}
However, when I try to validate against the following user-input object, it succeeds. Shouldn't it fail because:
(1) there is no "properties" element in the initial metadata+schema definition? This field seems to be required based on the examples shown here: https://www.npmjs.com/package/jsonschema
(2) the type for grade is not a number
What am I doing wrong?
The validation is passing because the schema is not well formed ("properties" is missing).
Try this instead and then the validation will fail:
{
"name": "schoolDemo",
"displayName": "School Demo",
"propertiesKey": "assetId",
"properties": {
"assetId": {
"type": "string"
},
"grade": {
"type": "number"
}
}
}
Here is the thing I'm trying to validate:
[REMOVED AFTER EDIT - PLEASE SEE EDIT BELOW FOR UP TO DATE CODE]
This should fail because only the item that should be acceptable here is "merchants" - but the validation doesn't fail. It passes.
I've can't work this out. I've tried a few approaches and it's got me nowhere.
What is wrong here?
---------------------- EDIT ----------------------------
I've been asked to provide more code. Here is the payload I need to validate. It's in PHP.
$payload = (object) [];
$payload->query_string = (object) [];
$payload->query_string->include = (object) [
"merchant_channel",
"merchant",
];
Here is the line that will run the validator:
$this->validator->validate(
$payload,
['$ref' => 'file://Schemas/the-json-file.json']
);
And here is the file that I'm running the validator against:
{
"type": "object",
"properties": {
"query_string": {
"type": "object",
"properties": {
"include": {
"type": "object",
"properties": {
"values": {
"type": "array",
"items": {
"allOf": [
{
"type": "string",
"enum": [
"language"
]
}
]
}
}
}
}
}
}
}
}
I'm using this package:
https://github.com/justinrainbow/json-schema
This package is quite simply....
A PHP Implementation for validating JSON Structures against a given Schema.
You shouldn't have to know PHP to able to answer my original question which is specific to JSON Schema Validation!
Please don't comment/answer saying something like "You've missed a quote" or "You've missed a closing bracket". Obviously I've had to cut this code down so I can post it on Stack Overflow.
It lacks starting and ending curly braces.
I used Extended Choice Parameter Script plugin and created a JSON editor with Array type as below:
disable_edit_json: true,
disable_properties: true,
disable_collapse: true,
theme: "jqueryui",
iconlib:"fontawesome4",
schema: {
"type": "object",
"title": "instances",
"properties": {
"instance": {
"type": "array",
"propertyOrder" : 1,
"format": "table",
"uniqueItems": true,
"items": {
"title": "instance",
"type": "object",
"properties": {
"url": {
"type": "string"
}
}
}
}
}
}
The parameter name is "ServerUrls". Using this I can pass one or many URLs to my Jenkins job, and I want to know the size of the array and access each of these parameter values from within a Groovy script. Conceptually something like ServerUrls.instance[0], ServerUrls.instance1 etc.
Just doing println params["ServerUrls"] throws an Exception.
Can someone please help?
It worked. The solution is as below, and it returns the value as JSON in a string format. It should be fairly easy to parse the JSON to obtain the internals of it.
def hardcoded_param = "ServerUrls"
def resolver = build.buildVariableResolver
def hardcoded_param_value = resolver.resolve(hardcoded_param)
println hardcoded_param_value