模式验证,如何根据较低级别的条件在顶层强制实施属性的存在

时间:2019-04-24 19:06:44

标签: json schema jsonschema json-schema-validator ajv

在解析yaml文件并将其解析为JSON之后,我试图编写一个架构来验证它。

假设这是我的.yml文件,其中包含2个顶级属性,汽车和车库。

汽车是可选的,而需要车库。

但是,车库的子属性之一是汽车。如果定义了车库下的汽车,我希望该模式确保也定义了顶层的汽车。否则,该架构将无效

cars:
  - BMW
  - Mercedes-Benz
  - Audi

garage:
  location: Miami
  cars:
    - BMW
    - Audi

我的模式:

{
  properties: {
    cars: {
       type: 'array',
       items: {
          type: 'string'
       }
     },
    garage: {
      type: 'object',
      properties: {
          location: {
            type: 'string'
           },
          cars: {
            type: 'array'
         }
    },
 required: ['garage']
}}

所以我尝试在顶层执行if-else

{
  if: { properties: { garage: { cars: {type: 'array'}}}},
  then: {required:['cars']},
  properties: {
    cars: {
       type: 'array',
       items: {
          type: 'string'
       }
     },
    garage: {
      type: 'object',
      properties: {
          location: {
            type: 'string'
           },
          cars: {
            type: 'array'
         }
    },
 required: ['garage']
}}

但是看来我做错了,或者没有达到目的。

在顶层也执行anyOf来匹配子方案对我来说不起作用。

有帮助吗?

2 个答案:

答案 0 :(得分:0)

if的值必须是JSON模式。 如果将if的值作为JSON Schema本身,并测试将其应用于JSON实例中正确位置的验证结果,则可以帮助您调试这种类型的问题。

在您的if块中,您需要将嵌套cars放在properties下,就像在主模式中所做的一样。

您可能还想制造if区域中所需的车库和汽车。]

但是,您无法定义是否希望将garage.cars的值包含在cars数组中。

答案 1 :(得分:0)

您可以使用“ JSON扩展结构模式”语言JESS指定引用完整性约束(以及所有其他要求)。

以下是完整的JESS模式,以单个JSON文档的形式呈现:

[ "&",
  ["&",
    {"::>=": {"garage": {"location": "string", "cars": [ "string" ] } } }
  ],
  {"ifcond": { "has": "cars" },
    "then": ["&", { "forall": ".[cars]", "schema": ["string"]  } ]
  },
  {"setof": ".[garage]|.[cars][]", "subsetof": ".[cars][]"}
]

第一个“&”介绍这三个要求的结合,最后一个是参照完整性约束。

JESS repository有一个架构一致性检查器,我用来对照上述架构来验证您​​的样本(表示为JSON)。