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

Можно ли настроить схему JSON, которая по-прежнему допускает additionalProperties, но не соответствует, если присутствует очень конкретное имя свойства? Другими словами, мне нужно знать, возможно ли иметь полную противоположность объявлению required.

Схема:

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" }
    },
    "required": [ "x" ],
    "ban": [ "z" ] // possible?
}

Соответствие:

{ "x": 123 }

Соответствие:

{ "x": 123, "y": 456 }

не совпадать:

{ "x": 123, "y": 456, "z": 789 }

person M Miller    schedule 28.05.2015    source источник


Ответы (5)


То, что вы хотите сделать, может быть достигнуто с помощью ключевого слова not. Если схема not проходит проверку, родительская схема не будет проверяться.

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" }
    },
    "required": [ "x" ],
    "not": { "required": [ "z" ] }
}
person Jason Desrosiers    schedule 05.06.2015
comment
Не требуется не означает, что не должно присутствовать. - person jruizaranguren; 09.06.2015
comment
@jruizaranguren, ты пытаешься сказать, что этот ответ неверен? Я могу расширить свое объяснение, если неясно, почему эта схема отвечает на вопрос. - person Jason Desrosiers; 10.06.2015
comment
Ты прав. Я не прав. Не надо расширять объяснение. - person jruizaranguren; 10.06.2015
comment
Хотя схема JSON верна, я разделяю замешательство @jruizaranguren по поводу логики. (К сожалению, не единственное место в схеме JSON. :/) - person Raphael; 05.07.2018
comment
Я также думаю, что это синтаксически запутанно (хотя это работает, чтобы избежать присутствия параметра). С другой стороны, валидаторы, которые я использовал, не дают явных ошибок в таких ситуациях. - person adripanico; 04.10.2019
comment
@adripanico - при первоначальном запросе не сработало бы, но с Draft 6+ комбинация not: {propertyNames: {enum: [bad, properties]}} хорошо работает с валидаторами, предоставляя определенные недопустимые имена свойств в возвращаемых ошибках. . - person RealBlueSky; 14.02.2020
comment
@JasonDesrosiers jruizaranguren пытается подразумевать, что not required означает even if it is there it doesn't matter. Это не проблема вашего ответа, а смысл синтаксиса схемы JSON. "not": { "required": [ "z" ] } не означает то же самое в естественном английском.. - person Romeo Sierra; 28.02.2020
comment
Привет, я пытаюсь добиться чего-то похожего на то, что спросил ОП. Я хочу запретить еще одно свойство, кроме z. Если я добавлю его в массив not required: not: {required: [z,y]} и в теле json я отправлю только свойства x и z, он проверит: это ожидаемое поведение? - person jrf; 06.04.2020
comment
@jrf Забавно, что ты спрашиваешь об этом, потому что я только что ответил на этот вопрос пару часов назад, и это не обычный вопрос. Раздел «Что случилось с required-not» должен ответить на ваш вопрос stackoverflow.com/a/61062869/1320693. - person Jason Desrosiers; 06.04.2020
comment
Вау, спасибо @JasonDesrosiers! Я искал эти темы в SO уже несколько дней, но ничего не нашел. Эти вопросы — именно то, что я пытаюсь сделать... Я думал, что слишком сильно расширяю возможности json-schema, но я думаю, что я не единственный! Спасибо! - person jrf; 06.04.2020

Есть более простой подход. Определите, что если x присутствует, он не должен удовлетворять никакой схеме. По доведению до абсурда x не может присутствовать:

{
    "properties" : {
        "x" : {
            "not" : {}

        }
    }
}

Обновление от 16 04 2020. Как указано в комментарии @Carsten, начиная с черновой версии 05 и выше, предлагаемую схему можно упростить следующим образом:

{
    "properties": {
       "x": false
    }
}
person jruizaranguren    schedule 09.06.2015
comment
Самый удобный и не запутанный ответ для меня. Особое преимущество в том, что оно находится внутри ключевого слова properties вместе с другими свойствами. - person 1valdis; 29.12.2018
comment
ИМО, это не ответ на этот конкретный вопрос, но это действительно хорошо. - person kris_IV; 05.12.2019
comment
Сокращением для ”x”: { ”not”: {} } в более новых черновых версиях будет ”x”: false. - person Carsten; 15.04.2020

Я решил проблему, запретив дополнительные свойства через "additionalProperties": false, но используя patternProperties, чтобы разрешить любое имя свойства, кроме запрещенного.

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" }
    },
    "required": [ "x" ],
    "patternProperties": {
        "^(?!^z$).*": {}
    },
    "additionalProperties": false
}
person M Miller    schedule 28.05.2015

Чтобы указать отсутствие поля, вы можете ожидать, что его тип будет null.

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" },
        "z": { "type": "null" }

    },
    "required": [ "x" ]
}
person Tomás Senart    schedule 25.01.2019
comment
Однако является ли «null» тем же, что и «undefined»? - person jamesjansson; 06.11.2019

Вы можете иметь тип null для этого конкретного свойства:

 z : {
"type": "null"
}
person swarnim gupta    schedule 17.08.2020