Какова логическая связь между ключевыми словами в схеме json?

Согласно спецификации (http://json-schema.org/schema) там не является взаимным исключением ключевых слов схемы. Например, я мог бы создать следующую схему:

{ 
    "properties" : {
        "foo" : {"type" : "string"}
    }
    "items" : [
       {"type" : "integer" },
       {"type" : "number" }
    ]
}

Будет ли эта схема проверяться как на объектах, так и на массивах? Если это так, это будет означать связь «ИЛИ» между ключевыми словами.

Но если мы рассмотрим следующую схему:

{ 
    "anyOf" : [
        { "type" : "string",},
        { "type" : "integer"}
    ]
    "not" : {
       { "type" : "string",
         "maxLength" : 5
       }
    }
}

Наиболее практичный способ интерпретации - это отношение «И» между ключевыми словами anyOf, а не ключевыми словами.

В черновике версии 4 я не нашел никаких указаний на логическое взаимодействие ключевых слов. Может ли кто-нибудь указать мне на документацию / стандарт, которые ответят на этот вопрос?


person egiordano747    schedule 08.01.2015    source источник


Ответы (2)


Ключевые слова всегда связаны отношением «И». Данные должны соответствовать всем ключевым словам из схемы.

Ключевые слова properties и items не определяют тип объекта (для этого вы должны использовать type). Вместо этого они имеют значение только для определенных типов и в противном случае игнорируются. Итак, properties на самом деле означает:

Если данные являются объектом, применяются следующие определения свойств ...

Это означает, что {"properties":{...}} будет соответствовать любой строке, потому что properties игнорируется для значений, не являющихся объектами. А items на самом деле означает:

Если данные представляют собой массив, применяются следующие определения элементов ...

Итак, комбинация И выглядит так:

(Если данные являются объектом, применяется properties) И (если данные являются массивом, применяется items)

person cloudfeet    schedule 08.01.2015
comment
Вместо того, чтобы говорить, что properties игнорируется для не-объектов, лучшая формулировка: properties игнорируется для любого значения JSON, которое не является объектом. - person fge; 09.01.2015

Как четко указано в спецификации, некоторые ключевые слова актуальны только для одного конкретного типа значения JSON или для всех из них.

Так, например, properties применяется только в том случае, если проверяемое значение JSON является объектом JSON. К любому значению JSON, которое НЕ является объектом, оно не будет применяться (другой способ понять это - если значение JSON для проверки не является объектом JSON, проверка по этому ключевому слову всегда будет успешной).

Точно так же items будет применяться только в том случае, если значение JSON является массивом JSON.

Теперь некоторые другие ключевые слова применимы ко всем типам; среди них enum, allOf, anyOf, oneOf, type. В каждом случае правила проверки четко определены в спецификации.

Вкратце: вы должны подумать, какое значение ожидается. Самый простой способ заставить значение иметь данный тип в схеме - использовать type, например:

"type": "integer"

НО это ключевое слово, тем не менее, будет применяться НЕЗАВИСИМО от всех остальных в процессе проверки. Итак, это юридическая схема:

{
    "type": "integer",
    "minItems": 1
}

Если на проверку передан пустой массив JSON, он не будет работать для обоих ключевых слов:

  • type, потому что значение не является массивом;
  • minItems, потому что значение является массивом, но у него нулевые элементы, что недопустимо для этого конкретного ключевого слова, поскольку оно ожидает хотя бы один элемент в массиве.

Обратите внимание, что результат проверки полностью не зависит от порядка, в котором вы оцениваете ключевые слова. Это фундаментальное свойство схемы JSON. И это в значительной степени требование, поскольку порядок членов в объекте JSON не имеет значения ({ "a": 1, "b": 2 } - это тот же объект JSON, что и { "b": 2, "a": 1 }).

И, конечно, если только ОДНО ключевое слово вызывает сбой проверки, все значение JSON недопустимо для схемы.

person fge    schedule 08.01.2015