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

Schema validation, how to enforce the existance of property at top level based on condition in lower level

我正在尝试编写一个模式来在将 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 以匹配子模式对我来说也不起作用..

有帮助吗?

if 的值必须是 JSON 架构。 如果您将 if 的值单独作为 JSON 架构并测试将其应用到 JSON 实例中正确位置的验证结果,它可能会帮助您调试此类型的问题。

在您的 if 块中,您需要将 nest cars 放在 properties 下,就像您在主架构中所做的那样。

您可能还想在 if 街区制作车库和汽车。]

但是,您不能定义要将 garage.cars 中的值包含在 cars 数组中。

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

这是作为单个 JSON 文档呈现的完整 JESS 模式:

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

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

JESS repository 有一个架构一致性检查器,我用它来根据上述架构验证您的示例(表示为 JSON)。