如何在具有多个IF的JSON Schema 6中使用Switch

时间:2017-09-08 18:23:28

标签: json jsonschema json-schema-validator

我有阵列的实体。我想基于名为dataStoreType的属性调用不同的实体类型。我的架构看起来像这样:

x

我的实例JSON看起来像这样:

const { environment } = require('@rails/webpacker');
const path = require("path");
const webpack = require('webpack');

environment.plugins.set(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
  })
);

environment.loaders.set('Handlebars', {
  test: /\.hbs$/,
  use: {
    loader: 'handlebars-loader',
    query: {
      knownHelpersOnly: false,
      helperDirs: [
        path.resolve(__dirname, "../..", "app/javascript/handlebars-helpers")
      ]
    }
  }
});

module.exports = environment;

但是我的Schema没有正确验证这个实例,因为我认为交换机中存在一些错误。我确信JSON没有被验证,因为我已经为实体定义了其他规则(我没有提到),当我的实例违反了该规则时,架构没有显示错误。

我的开关中的错误可能是什么

2 个答案:

答案 0 :(得分:1)

你的主要问题是你所拥有的地方:

"properties": {"dataStoreType": "RELATIONAL"}

你真正需要的是:

"properties": {"dataStoreType": {"const": "RELATIONAL"}}

除此之外,请注意switch不再是JSON架构提案,但if / then / else已被接受用于下一个草稿(草案-07) )。因此,当使用启用了早期if支持的Ajv或其他验证程序时,或者当它出来并支持时移动到draft-07时,您需要:

"entities":{
  "type":"array",
  "oneOf": [
    {
      "if": {"properties":{"dataStoreType":{"const":"RELATIONAL"}}},
      "then":{"$ref": "#/definitions/entities-relational"}
    },
    {
      "if": {"properties":{"dataStoreType":{"const":"DOCUMENT"}}},
      "then":{"$ref": "#/definitions/entities-no-sql"}
    },
    {
      "if": {"properties":{"dataStoreType":{"const":"KEYVALUE"}}},
      "then":{"$ref": "#/definitions/entities-key-value"}
    }
  ]
}

这相当于一个开关(没有掉头)或一组链接的else-ifs(也可以工作,但是你越来越难以读取你的链)。

您的if条件是互斥的,因此oneOf适用于此,并且可以按照您的意愿行事。

我肯定会避免使用switch,因为它已作为该标准的提案被彻底拒绝。它不太可能被添加。

答案 1 :(得分:0)

JSON Schema Draft 6不支持"if""then"个关键字。它是currently a proposal。可能你使用已经支持它的实现(ajv,也许?)。

另一方面,您可以通过以下方式使用"oneOf""const"来实现您想要的效果:

{
    "oneOf" : [
        {
            "type": "object",
            "properties": {
                "dataStoreType": {
                    "const": "RELATIONAL"
                },
                "entities": {
                    "type": "array",
                    "items": {    
                        "$ref": "#/definitions/entities-relational"
                    }
                }
            }
        },
        {
            "type": "object",
            "properties": {
                "dataStoreType": {
                    "const": "DOCUMENT"
                },
                "entities": {
                    "type": "array",
                    "items": {    
                        "$ref": "#/definitions/entities-no-sql"
                    }
                }
            }
        },
        // and here comes the KEYVALUE schema.. I think you get it now
    ]
}