Схема JSON условная: требовать и не требовать - PullRequest
0 голосов
/ 20 ноября 2018

вопрос 1. Я пытаюсь реализовать это условие: если специальное свойство существует, другое свойство требует, но если оно не существует, другое свойство не требует вопроса 2. в схеме json мы можем использовать не в зависимостях?Вот пример схемы

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

, если «средний», то требуется «громоздкий», иначе не требуется громоздкий.«не требуется» означает, что если «среднего» не существует, то громоздкое «не должно присутствовать»

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Существует несколько способов достижения требуемого эффекта даже без использования JSON Schema draft-07 if-then-else .

логический оператор и импликация (draft-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

Проверьте здесь для справки:

Схема JSON - действительна, если объект * не * содержит определенное свойство

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

"anyOf" - логическое ИЛИ, "oneOf" - XOR, "allOf«- AND,« not »- отрицание, но обратите внимание на спецификацию:

Экземпляр действителен для этого ключевого слова, если он не может успешно выполнить проверку по схеме, определенной этим ключевым словом.

draft-06 - зависимости + propertyNames

Наиболее очевидно.Я не уверен, что вы исключили этот вопрос в своем вопросе, так что оставьте здесь на всякий случай.Обратите внимание, что вместо «AdditionalProperties», если вы не хотите просто ограничивать допустимые ключи, можно использовать «propertyNames» (и фактически это то, для чего оно было добавлено).

"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

Обновление

После уточнения в комментарии:

для draft-6 - здесь «не требуется» означает, что если «среднего» не существует, то громоздкий «не должен присутствовать»

«не должен» означаетпредотвращение громоздкого присутствия.

Я перефразирую ваше состояние:

1.если «средний» существует, «громоздкий» должен присутствовать -> оба ключа должны присутствовать одновременно

2.если «среднего» не существует, «громоздкий» не должен присутствовать также -> обе клавиши не должны присутствовать одновременно

Может«громоздкий» существует, а «средний» не существует?

Нет.См. 2. И наоборот (см. 1.).Булево равенство (дополняющее логическое XOR).

Таким образом, если «громоздкий» существует - это значит, что «средний» должен быть всегда ... Это означает, что оба обязательны или оба не должно быть обязательным (или даже разрешенным) .

Поскольку это draft-06, вы также можете использовать "propertyNames" для определения разрешенных имен свойств (вид ярлыка для этой логики).

логический оператор и импликация (draft-06 и выше)

Правильная логическая операция, преобразованная в схему JSOn, будет выглядеть следующим образом:

"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"] } },
    ]
  }
]

XOR - ИЛИ (оба требуются) ИЛИ (средний не требуется И громоздкий не требуется).

Обратите внимание, что я не делаю "not": {"required": ["medium", "громоздкий"]} как при наличии только одного из этих ключей "требуемая «схема потерпит неудачу, что будет означать, что« нет »вернет успешный результат проверки.Нужно перефразировать его, используя законы де Моргана:

"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",

    },
  ]
}

Это отвечает на ваш вопрос?

0 голосов
/ 21 ноября 2018

Схема JSON Draft-07 включает эти новые ключевые слова if, then и 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);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>

Надеюсь, это имеет смысл, и вы можете соответствующим образом адаптировать свой код.

PS: в вашей схеме у вас есть свойство require, которое яя не уверен, что является допустимым ключевым словом JSON Schema.Вы, вероятно, имели в виду required вместо.

...