admin管理员组

文章数量:1315481

I am using the AJV package in my node.js project.

I am trying to validate some data against a couple of schema files. Both of these schema files are in the same directory:

/dir
    |
    parent_schema.json
    |
    sub_schema.json
/data
    |
    data.json

I am trying to get a super simple example of the $ref property working but I am having trouble. parent_schema.json looks like:

{
  "properties": {
    "foo": { "type": "string" },
    "bar": { "$ref": "sub_schema.json" }
  }
}

And sub_schema.json looks like:

{
  "properties": {
    "sub1": { "type": "string" },
  }
}

And I am trying to validate my data.json which for the sake of pleteness looks like:

{
  "foo": "whatever",
  "bar": {
    "sub1": "sometext"
  }
}

The issue I'm having is with my $ref path. I am getting this error from AJV:

MissingRefError {
    message: "can't resolve reference subschema1.json from id #"
    missingRef: "subschema1.json"
    missingSchema: "subschema1.json"
}

Anyone see what's wrong with my path? I know you are also supposed to use the # to select what specific property you want matched against, but I want the ENTIRE schema to be used.

I am using the AJV package in my node.js project.

I am trying to validate some data against a couple of schema files. Both of these schema files are in the same directory:

/dir
    |
    parent_schema.json
    |
    sub_schema.json
/data
    |
    data.json

I am trying to get a super simple example of the $ref property working but I am having trouble. parent_schema.json looks like:

{
  "properties": {
    "foo": { "type": "string" },
    "bar": { "$ref": "sub_schema.json" }
  }
}

And sub_schema.json looks like:

{
  "properties": {
    "sub1": { "type": "string" },
  }
}

And I am trying to validate my data.json which for the sake of pleteness looks like:

{
  "foo": "whatever",
  "bar": {
    "sub1": "sometext"
  }
}

The issue I'm having is with my $ref path. I am getting this error from AJV:

MissingRefError {
    message: "can't resolve reference subschema1.json from id #"
    missingRef: "subschema1.json"
    missingSchema: "subschema1.json"
}

Anyone see what's wrong with my path? I know you are also supposed to use the # to select what specific property you want matched against, but I want the ENTIRE schema to be used.

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jun 12, 2020 at 16:34 RoseyRosey 8311 gold badge14 silver badges29 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 10

It's a mon misconception that $ref somehow "loads" a file.

See what ajv.js says:

$ref is resolved as the uri-reference using schema $id as the base URI (see the example).

And:

You don’t have to host your schema files at the URIs that you use as schema $id. These URIs are only used to identify the schemas, and according to JSON Schema specification validators should not expect to be able to download the schemas from these URIs.

Ajv won't try loading this schema from stack://over.flow/string for example:

{
  "$id": "stack://over.flow/string",
  "type": "string"
}

If you want to reference that schema in another schema, they both need to have the same base URI stack://over.flow/ e.g.,

{
  "$id":  "stack://over.flow/object",
  "type": "object",
  "properties": {
    "a": { "$ref": "string#" }
  }
}

Here { "$ref": "string#" } says "import the schema at stack://over.flow/string" so you end up with:

{
  "$id":  "stack://over.flow/object",
  "type": "object",
  "properties": {
    "a": {
      "$id": "stack://over.flow/string",
      "type": "string"
    }
  }
}

This allows you to bine small schemas:

const ajv = new Ajv;

ajv.addSchema({
  "$id": "stack://over.flow/string",
  "type": "string"
});

ajv.addSchema({
  "$id": "stack://over.flow/number",
  "type": "number"
});

const is_string = ajv.getSchema("stack://over.flow/string");
const is_number = ajv.getSchema("stack://over.flow/number");

console.log(is_string('aaa'), is_string(42));
console.log(is_number('aaa'), is_number(42));

const is_ab = ajv.pile({
  "$id":  "stack://over.flow/object",
  "type": "object",
  "properties": {
    "a": { "$ref": "string#" },
    "b": { "$ref": "number#" }
  }
});

console.log(is_ab({a: "aaa", b: 42}));
console.log(is_ab({a: 42, b: "aaa"}));
<script src="https://cdnjs.cloudflare./ajax/libs/ajv/6.12.2/ajv.min.js"></script>


(Please note that in your example both schemas are incorrect. You're missing {"type": "object"} in both.)

To answer your question:

const ajv = new Ajv;

ajv.addSchema({
  "$id": "stack://over.flow/parent.schema",
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "$ref": "child.schema#" }
  }
});

ajv.addSchema({
  "$id": "stack://over.flow/child.schema",
  "type": "object",
  "properties": {
    "sub1": { "type": "string" },
  }
});

const is_parent = ajv.getSchema("stack://over.flow/parent.schema");
const is_child = ajv.getSchema("stack://over.flow/child.schema");

console.log(is_parent({
  "foo": "whatever",
  "bar": {
    "sub1": "sometext"
  }
}));
<script src="https://cdnjs.cloudflare./ajax/libs/ajv/6.12.2/ajv.min.js"></script>

本文标签: javascriptHow do you make json ref to local filesStack Overflow