当前位置: 首页 > 知识库问答 >
问题:

与AJV一起使用的json-schema的正确用法是什么?

公良昕
2023-03-14

早上好,当对同一个json文件中定义的内容使用$ref时,我在使用ajv和json-schema时遇到了一个问题。我怀疑问题出在ids的使用上,我会更理解这一点。

我的文件是:

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

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

共有1个答案

於子晋
2023-03-14

您的直觉是正确的,$ref没有像您预期的那样解析,因为$id$ref是根据架构的$id解析的。在本例中,{“$ref”:“#/definitions/person”}根据“$id”:“http://asite.org/schemas/member.json”解析,结果是http://asite.org/schemas/member.json#/definitions/person不存在。解决方案是使用person模式$ID而不是相对路径:{“$ref”:“person.json”}

另外,您可能更喜欢用于编译模式的备用API,该API在处理捆绑模式时效果更好,比如您的“definitions.json”。您可以加载整个文件,然后通过$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");
 类似资料:
  • 我尝试使ajv使用两个JSON-Schema,一个依赖于另一个。下面是我的模式的一个示例(简化): json 错误:没有带有键或引用“http://json-schema.org/draft-04/schema#”的模式 更新:如果我从types.json中删除“$schema…”,我得到的错误是: MissingReferror:无法从id#中解析引用types.json#/definition

  • Spring Boot 2.1.2在https://github.com/spring-projects/spring-boot/blob/v2.1.2中将Elasticsearch版本定义为6.4.3。release/spring-boot-project/spring-boot-dependencies/pom.xml。 但是,Spring Data Elasticsearch在https:/

  • 我们使用Azure存储队列作为传输在Azure辅助角色中运行NServiceBus 4.6。 我们很乐意使用默认的Azure表存储持久器存储NServiceBus相关数据(sagas、订阅等)。 不过,我们希望将业务实体存储在RavenDB中,以利用查询和Raven的其他功能。 鉴于Azure缺乏事务支持,在我们的处理程序中配置NServiceBus和使用Raven的/的最佳方式是什么。我们希望确

  • 我已经设法用HK2注入技术实现了Jersey/Jetty的工作设置,但鉴于我发现的大量文档有些令人困惑(有时甚至不一致),我不确定是否遗漏了一些重要的细节。就目前而言,我是这样引导servlet的; 我将我的应用程序资源配置为; 我的AppBinder为: 这一切都适用于我的简单测试用例,但有几件事我不清楚。泽西文档引用了一个我应该扩展的应用程序类,并使用Injections.addBinding

  • 问题内容: 即使在使用Java Swing一年以上之后,对我来说,它仍然像魔术一样。如何正确使用BufferStrategy,尤其是方法? 我想添加一个JFrame和一个Canvas,然后进行绘制。我还希望能够调整()画布的大小。每次我调整Canvas的大小时,似乎都会被浪费掉,或者变得毫无用处,因为在上使用并没有真正做任何事情。另外,它具有怪异的不确定性行为,我不知道如何正确同步它。 这就是我的

  • 问题内容: 我想在Linux上使用该机制。我希望我的应用程序知道何时更改了文件。能否请您提供给我一个示例,该怎么做? 问题答案: 文档(来自具有inotify的Monitor文件系统活动) 在C API 提供了三个系统调用来构建各种文件系统监视器: 在内核中创建子系统的实例,并在成功和失败时返回文件描述符。与其他系统调用一样,如果失败,请检查诊断。 顾名思义,它增加了一块 手表 。每个监视都必须提