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

h.a*_*aie 5 jsonschema

我正在尝试实现这种条件:如果存在一个特定的属性,则需要另一个属性;但如果不存在,则不需要另一个。

另外,在JSON模式中,可以不使用依赖项吗?

这是一个示例架构

var schema = {
    "properties": {
        "smaller": {
            "type": "number"
        },
        "larger": { "type": "number" },
        "medium":{'type':'string'},
        "bulky":{'type':'string'}
    },
    require:['smaller','larger'],
    additionalProperties:false
};
Run Code Online (Sandbox Code Playgroud)

如果存在“中等”,则需要“庞大”。否则,不需要“庞大”。

此处的“不需要”是指如果“中”不存在,则必须不存在大体积。

Psy*_*ish 7

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

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

这里的逻辑含义是:如果存在“中等”,则需要将“庞大”翻译成不存在的“中等”,或者“需要”“庞大”(后者意味着存在“中等”),可以进一步阐述为“ “中等”或“大”是必需的(因为如果存在“中等”,它将满足所要求的条件)。请参见以下架构:

"properties": {
  "smaller": {"type": "number"},
  "larger": { "type": "number" },
  "medium":{"type":"string"},
  "bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [ 
  { 
    "not" : { "required" : ["medium"] }
  },
  {
    "required" : ["bulky"]
  }
],
"additionalProperties" : false
Run Code Online (Sandbox Code Playgroud)

检查这里供参考:

JSON模式-如果对象*不*包含特定属性,则有效

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

“ anyOf”-逻辑OR,“ 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"
  ]
}
Run Code Online (Sandbox Code Playgroud)

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

更新资料

在评论中澄清后:

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

“必须”是指防止体积大。

我将重述您的情况:

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

2.如果“ medium”不存在,则“ bulky”也不能同时出现->两个密钥不能同时出现

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

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

因此,如果“大量”存在-则意味着“中”必须始终存在...这意味着这两个条件都是必需的,或者两个条件都不是必需的(甚至不允许)

由于它是草案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"] } },
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

XOR-EITHER(都需要)或(不要求中等和不要求体积大)。

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

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

但是,使用“ 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",

    },
  ]
}
Run Code Online (Sandbox Code Playgroud)

它能回答您的问题吗?


cus*_*der 5

JSON Schema Draft-07 包含了这些新关键字 ifthen它们else允许您拥有条件模式。

在这个例子中:

  • 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);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

希望这是有意义的,您可以相应地调整您的代码。

PS:在您的架构中,您有一个require我不确定是否是有效的 JSON 架构关键字的属性。你的意思可能是required相反。