JSON模式条件:要求和不要求

时间:2018-11-20 17:36:05

标签: jsonschema

问题1.我正在尝试实现这种条件:如果存在一个特殊属性,则需要另一个属性,但是如果不存在,则不需要另一个属性 问题2.在json模式中,我们可以不依赖使用吗? 这是一个示例架构

var schema = {
    "properties": {
        "smaller": {
            "type": "number"
        },
        "larger": { "type": "number" },
        "medium":{'type':'string'},
        "bulky":{'type':'string'}
    },
    require:['smaller','larger'],
    additionalProperties:false
};

如果“中等”则要求“大”,否则不需要大。 这里的“不需要”表示如果“中等”不存在,那么笨重的“一定不能存在”

3 个答案:

答案 0 :(得分:5)

即使不使用JSON Schema draft-07 if-then-else ,也有几种方法可以达到要求的效果。

逻辑运算符及其含义(草稿04及更高版本)

此处的逻辑含义:如果存在“中”,则要求“大” 可以翻译为“中”,或者“要求”“大” (后者表示存在“ medium” ),可以进一步详细说明为“ medium”不是必需的,或者是“ bulky”为“ required” (因为如果“ medium”为目前,它将满足所需条件)。参见以下架构:

"properties": {
  "smaller": {"type": "number"},
  "larger": { "type": "number" },
  "medium":{"type":"string"},
  "bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [ 
  { 
    "not" : { "required" : ["medium"] }
  },
  {
    "required" : ["bulky"]
  }
],
"additionalProperties" : false

在此处检查以供参考:

JSON schema - valid if object does *not* contain a particular property

http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7

“ anyOf”-逻辑或,“ oneOf”-XOR,“ allOf”-AND,“ not”-取反,但请注意规范:

  

如果实例无法针对此关键字定义的架构成功验证,则该实例对该关键字有效。

草稿-06-依赖项+ propertyNames

最明显。我不确定您是否在问题中排除了这一点,因此以防万一。请注意,如果您不想简单地限制有效密钥,则可以使用“ propertyNames”(而不是“ additionalProperties”)(实际上是为其添加的)。

"properties": {
  "smaller": {"type": "number"},
  "larger": { "type": "number" },
  "medium":{"type":"string"},
  "bulky":{"type":"string"}
},
"required":["smaller","larger"],
"dependencies" : {
  "medium" : ["bulky"]
},
"propertyNames" : {
  "enum" : [
    "smaller",
    "larger",
    "medium",
    "bulky"
  ]
}

在此处检查以供参考:http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7

更新

在评论中澄清后:

  

第6草案-这里的“不需要”表示如果“中等”不存在,那么笨重的“一定不能存在”

“不得”是指防止体积大。

我将重述您的病情:

1。如果“中”存在,则“大”必须存在->两个密钥必须同时存在

2。如果“中”不存在,则“大” 也不能存在->两个键一定不能同时存在

是否可以存在“庞大”而“中等”不存在?

不。请参阅2。反之亦然(请参阅1.)。布尔等式(与逻辑XOR互补)。

因此,如果“大量”存在-则意味着“中等”必须始终存在...这意味着两者都是必需,或者都不需要(甚至不允许) / em>。

因为它是草案06,所以您还可以使用“ propertyNames” 来定义允许的属性名称(这种逻辑的捷径)。

逻辑运算符及其含义(06和更高版本)

翻译为JSOn Schema的正确逻辑操作如下:

"oneOf" : [
  { "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
  {
    "allOf" : [   <== !medium ^ !bulky - due to how "not" works in schema context
      {"not" : { "required" : ["medium"] } },  
      {"not" : { "required" : ["bulky"] } },
    ]
  }
]

异或-(两者都是必需的)或(不需要介质,不需要体积大的)。

请注意,我没有执行“ not”:{“ required”:[“ medium”,“ bulky”]} ,因为只有这些键之一存在时,“ required”模式才会失败,表示“不”将返回成功的验证结果。需要使用de Morgans法来重新定义它:

"oneOf" : [
  { "required" : ["medium","bulky"] },
  {
    "not" : {   <=== !medium ^ !bulky = !(medium v bulky)
      "anyOf" : [
        { "required" : ["medium"] },
        { "required" : ["bulky"]  },
      ]
    }
  }
]

但是,使用“ propertyNames”也可以解决问题。 请参阅以下架构:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "properties": {
    "smaller": {"type": "number"},
    "larger": { "type": "number" },
    "medium":{"type":"string"},
    "bulky":{"type":"string"}
  },
  "required":["smaller","larger"],
  "anyOf" : [ 
    { 
       "required" : ["medium","bulky"]
    },
    {
      "propertyNames" : {
        "enum" : [
          "smaller",
          "larger"
        ]
      },
    }
  ],
  "examples" : [
    {
      "smaller" : 1,
      "larger" : 2,


    },
    {
      "smaller" : 1,
      "larger" : 2,
      "bulky" : "test",
      "medium" : ""
    },
    {
      "smaller" : 1,
      "larger" : 2,

      "medium" : ""
    },
    {
      "smaller" : 1,
      "larger" : 2,
      "bulky" : "test",

    },
  ]
}

它能回答您的问题吗?

答案 1 :(得分:2)

JSON Schema Draft-07已包含these new keywords ifthenelse,它们使您可以使用条件模式。

在此示例中:

  • 仅需要foo属性
  • 但是,如果将foo设置为"bar",则bar属性也将成为必填项

var ajv = new Ajv({
  allErrors: true
});

var schema = {
  "properties": {
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "string"
    },

  },
  "required": ["foo"],
  "if": {
    "properties": {
      "foo": {
        "enum": ["bar"]
      }
    }
  },
  "then": {
    "required": ["bar"]
  }
}

var validate = ajv.compile(schema);

test({
  "foo": "bar",
  "bar": "baz"
}); // VALID

test({
  "foo": "xyz"
}); // VALID

test({
  "foo": "bar",
}); // NOT VALID


function test(data) {
  var valid = validate(data);
  if (valid) console.log('VALID', data);
  else console.log('NOT VALID', data);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>

希望这是有道理的,您可以相应地修改代码。

PS:在您的模式中,您具有require属性,但我不确定这是有效的JSON Schema关键字。您可能是用required来代替的。

答案 2 :(得分:0)

如果您有多个依赖于各自值的属性,则可以使用属性依赖项。

{
  "type": "object",
  "properties": {
    "weight_1": {
        "type": "integer"
    },
    "weight_2": {
        "type": "integer"
    },
    "description_1": {
        "type": "string" 
    },
    "description_2": {
        "type": "string" 
    }
  },
  "allOf": [
    {
        "if": {
          "properties": {
            "weight_1": {
                "minimum": 10 
            }
          }
        },
        "then": {
          "dependencies": {
            "weight_1": ["description_1"]
          }
        }
    },
    {
        "if": {
          "properties": {
            "weight_2": {
                "minimum": 100
            }
          }
        },
        "then": {
          "dependencies": {
            "weight_2": ["description_2"]
          }
        }
    }
  ]
}