简体   繁体   English

具有未知属性的对象的 AJV 模式验证

[英]AJV schema validation for object with unknown properties

I have a funny scenario all over my platform, but I believe it's the best.我的整个平台都有一个有趣的场景,但我相信这是最好的。 I am trying to validate a JSON Schema where an object has unknown keys with the same schema as value.我正在尝试验证 JSON 模式,其中对象具有与值具有相同模式的未知键。 The keys are unique ID's and the value of those keys have the same schema.键是唯一的 ID,这些键的值具有相同的架构。

To understand it, let me explain with a sample code:为了理解它,让我用一个示例代码来解释:

let survey_questions = {
  "vv4sD32": {
    question: "Do you like dogs?",
    answers: ["Yes", "No"]
  },
  "df4sdIU": {
    question: "How about cats?",
    answers: ["Maybe", "Maybe not"]
  },
  "cbkle12": {
    question: "What do you prefer most?",
    answers: ["Dogs", "Cats"]
  }
}

As you can see, that sample is a survey, where the key is the unique ID of the question, and the value is an object with a shared schema.如您所见,该示例是一个调查,其中键是问题的唯一 ID,值是具有共享架构的对象。 I know I could loop though them and check the schema on each individual question, but I have examples of nested things of these type, and would complicate things a lot.我知道我可以遍历它们并检查每个单独问题的模式,但是我有这些类型的嵌套事物的示例,并且会使事情复杂化很多。 Any suggestions how to do this with AJV, or any other library?关于如何使用 AJV 或任何其他库执行此操作的任何建议?

Thank you,谢谢,

Carlino卡利诺

如果有人仍然会对此进行研究,那么patternProperties https://ajv.js.org/json-schema.html#patternproperties 可以很好地解决这个问题

There are great answers here.这里有很好的答案。 At the end, I ended up creating my own library I've been using for years and that has become quite popular recently.最后,我最终创建了自己的库,我一直在使用多年,并且最近变得非常流行。 The library is https://www.npmjs.com/package/great-json-validator checking for the data type “array-object”.该库是https://www.npmjs.com/package/great-json-validator检查数据类型“array-object”。 The documentation has a very google example.该文档有一个非常谷歌的例子。

Any suggestions how to do this with AJV or any other library?任何建议如何使用 AJV 或任何其他库执行此操作?

If you're open to a simple approach based on structural schemas, then please read on.如果您对基于结构模式的简单方法持开放态度,请继续阅读。

The command-line program can be used to check JSON schemas. 命令行程序可用于检查 JSON 模式。

This can be done in a variety of ways.这可以通过多种方式完成。 In this response, I'll focus on the use of a schema-inference engine (which I wrote) available at https://gist.github.com/pkoppstein/a5abb4ebef3b0f72a6ed在此回复中,我将重点介绍使用https://gist.github.com/pkoppstein/a5abb4ebef3b0f72a6ed提供的模式推理引擎(我编写的)

This inference engine produces an easy-to-read schema in the form of a JSON document that has the same structure as the JSON entities under examination.此推理引擎以 JSON 文档的形式生成易于阅读的架构,该架构与所检查的 JSON 实体具有相同的结构。

To illustrate, let's first assume:为了说明,让我们首先假设:

  • the file named survey_questions.json holds valid JSON along the lines suggested by the "survey_questions" object in the OP.名为survey_questions.json 的文件根据OP 中的“survey_questions”对象建议的行保存有效的JSON。

  • the above-mentioned schema.jq file has been downloaded to the directory ~/.jq/schema/上面提到的schema.jq文件已经下载到目录~/.jq/schema/

Now invoking jq at the command line like this:现在在命令行调用 jq 如下:

jq 'include "schema" {"search": "~/.jq"}; [.[]] | schema
' survey_questions.json 

produces the inferred structural schema:产生推断的结构模式:

{
  "question": "string",
  "answers": [
    "string"
  ]
}

This can be read as follows: each question is a JSON object with at most two keys:这可以理解为:每个问题都是一个 JSON 对象,最多有两个键:

  • a string-valued key named "question"一个名为“问题”的字符串值键

  • a key named "answers", which is always an array of strings.一个名为“answers”的键,它总是一个字符串数组。

Notice that schema.jq makes no inferences regarding the length of arrays.请注意,schema.jq 不会对数组的长度进行推断。 To check that each "answers" array has length of at least 2 would have to be done separately.要检查每个“答案”数组的长度是否至少为 2,必须单独完成。

Now suppose we added a third possible value, a number, to one of the allowed "answers".现在假设我们向允许的“答案”之一添加了第三个可能的值,一个数字。

Then the inferred schema would be:那么推断的模式将是:

{
  "question": "string",
  "answers": [
    "scalar"
  ]
}

Notice that answers is now inferred to be an array of scalars.请注意,现在将answers推断为标量数组。

Summary概括

In summary, if the intended schema of a set of JSON documents or entities can be expressed in the "structural" manner supported by schema.jq, then schema checking can be accomplished by comparing the inferred schema with the expected schema.总之,如果一组 JSON 文档或实体的预期模式可以以 schema.jq 支持的“结构”方式表达,那么模式检查可以通过将推断模式与预期模式进行比较来完成。

Any suggestions how to do this with AJV or any other library?任何建议如何使用 AJV 或任何其他库执行此操作?

You could use the JSON Extended Structural Schema language, JESS , which now comes with a conformance checker (JESS.jq);您可以使用 JSON 扩展结构模式语言JESS ,它现在带有一致性检查器 (JESS.jq); it requires to run.它需要才能运行。

In JESS, schemas consist of one or more JSON texts.在 JESS 中,模式由一个或多个 JSON 文本组成。 Your requirements can be specified by the following schema:您的要求可以由以下架构指定:

[
  "&",
  {
    "forall": ".[]",
    "schema": {
      "question": "string",
      "answer": [
        "string"
      ]
    }
  }
]

This can be read: for all values of the top-level keys, check that the value is an object matching the indicated pattern.这可以读取:对于顶级键的所有值,检查该值是否是与指定模式匹配的对象。

To determine whether your survey_questions is valid, you could (after installing JESS) use the JESS script as follows:要确定您的survey_questions是否有效,您可以(安装 JESS 后)使用 JESS 脚本,如下所示:

JESS --schema schema.json survey_questions.json

where schema.json holds the above schema, and survey_questions.json holds the JSON to be checked.其中schema.json保存了上述模式,而survey_questions.json 保存了要检查的JSON。

Note: I am the author of the JESS repository.注意:我是 JESS 存储库的作者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM