javascript - 你如何使 json $ref 到本地文件?
问题描述
我在我的 node.js 项目中使用AJV包。
我正在尝试针对几个模式文件验证一些数据。这两个模式文件都在同一个目录中:
/dir
|
parent_schema.json
|
sub_schema.json
/data
|
data.json
我正在尝试获得一个超级简单的$ref
属性工作示例,但我遇到了麻烦。parent_schema.json
好像:
{
"properties": {
"foo": { "type": "string" },
"bar": { "$ref": "sub_schema.json" }
}
}
sub_schema.json
看起来像:
{
"properties": {
"sub1": { "type": "string" },
}
}
为了完整起见,我正在尝试验证我的data.json
哪个看起来像:
{
"foo": "whatever",
"bar": {
"sub1": "sometext"
}
}
我遇到的问题是我的$ref
路径。我从 AJV 收到此错误:
MissingRefError {
message: "can't resolve reference subschema1.json from id #"
missingRef: "subschema1.json"
missingSchema: "subschema1.json"
}
有人看到我的路径有什么问题吗?我知道您还应该使用#
来选择要匹配的特定属性,但我希望使用 ENTIRE 模式。
解决方案
$ref
以某种方式“加载”文件是一种常见的误解。
看看ajv.js.org 怎么说:
$ref 被解析为使用模式 $id 作为基本 URI 的 uri-reference(参见示例)。
和:
您不必在用作架构 $id 的 URI 上托管架构文件。这些 URI 仅用于识别模式,根据 JSON 模式规范,验证器不应期望能够从这些 URI 下载模式。
Ajv 不会尝试从stack://over.flow/string
例如以下位置加载此架构:
{
"$id": "stack://over.flow/string",
"type": "string"
}
如果您想在另一个模式中引用该模式,它们都需要具有相同的基本 URI stack://over.flow/
,例如,
{
"$id": "stack://over.flow/object",
"type": "object",
"properties": {
"a": { "$ref": "string#" }
}
}
这里{ "$ref": "string#" }
说“在堆栈中导入架构://over.flow/string”所以你最终得到:
{
"$id": "stack://over.flow/object",
"type": "object",
"properties": {
"a": {
"$id": "stack://over.flow/string",
"type": "string"
}
}
}
这允许您组合小模式:
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>
推荐阅读
- javascript - 如何从 nextjs 上的处理程序访问状态?
- c++ - 如何在 C++ 中将 cout 更改为 printf?或者如何使控制台应用程序运行得更快?
- dataframe - 数据框索引值
- android - 使用 Kotlin 打印给定范围内的 nubers 1、3、6、10、15、21
- javascript - 是否可以使用 sms: url 预填充带有正文但没有收件人的消息?
- java - Jackson:使用标签列表序列化对象
- c# - 将 ISchemaFilter 示例转换为 Swashbuckle 5.0
- python - SQLAlchemy:两个日期之间的差异
- java - 当我们知道内存使用量低的大小时,从输入流中读取文件的快速方法
- javascript - 通过单击另一页面上的元素在一个页面中加载特定的 JSON 数据