你如何使json $ ref到本地文件? [英] How do you make json $ref to local files?

查看:71
本文介绍了你如何使json $ ref到本地文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在node.js项目中使用 AJV 包.

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

我正在尝试获取$ref属性的超简单示例,但遇到了麻烦. parent_schema.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" }
  }
}

sub_schema.json看起来像:

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

我正在尝试验证我的data.json,出于完整性的考虑,它如下:

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

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

我遇到的问题与我的$ref路径有关.我从AJV收到此错误:

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"
}

有人知道我的路线出了什么问题吗?我知道您也应该使用#选择要与之匹配的特定属性,但是我希望使用ENTIRE模式.

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.

推荐答案

常见的误解是$ref以某种方式加载"文件.

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

看看 ajv.js.org 怎么说:

使用架构$ id作为基本URI,将$ ref解析为uri引用(请参见示例).

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

并且:

您不必将架构文件托管在用作架构$ id的URI上.这些URI仅用于标识模式,根据JSON Schema规范,验证器不应期望能够从这些URI下载模式.

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不会尝试从stack://over.flow/string加载此架构:

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

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

如果您要在其他模式中引用该模式,则它们都必须具有相同的基本URI stack://over.flow/,例如

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#" }
  }
}

在这里{ "$ref": "string#" }将模式导入stack://over.flow/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 combine 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.compile({
  "$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.com/ajax/libs/ajv/6.12.2/ajv.min.js"></script>

(请注意,在您的示例中,两个模式都不正确.在两个模式中均缺少{"type": "object"}.)

回答您的问题:

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.com/ajax/libs/ajv/6.12.2/ajv.min.js"></script>

这篇关于你如何使json $ ref到本地文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆