Почему проверка JSON всегда успешна при использовании этой схемы, содержащей ‘allOf’?

#python #json #json-schema-validator #python-jsonschema

#python #json #json-schema-validator #python-jsonschema

Вопрос:

У меня есть схема JSON, с помощью которой я хочу проверить некоторые данные, используя python и модуль jsonschema. Однако это работает не совсем так, как ожидалось, поскольку некоторые принятые данные вообще не кажутся действительными (для меня и цели моего приложения). К сожалению, схема предоставлена, поэтому я не могу изменить саму схему — по крайней мере, не вручную.

Это сокращенная версия схемы (‘schema.json’ в коде ниже):

 {
  "type": "object",
  "allOf": [
    {
      "type": "object",
      "allOf": [
        {
          "type": "object",
          "properties": {
            "firstName": {
              "type": "string"
            },
            "lastName": {
              "type": "string"
            }
          }
        },
        {
          "type": "object",
          "properties": {
            "language": {
              "type": "integer"
            }
          }
        }
      ]
    },
    {
      "type": "object",
      "properties": {
        "addressArray": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "streetNumber": {
                "type": "string"
              },
              "street": {
                "type": "string"
              },
              "city": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  ]
}
  

Это пример того, что должно быть допустимым экземпляром (‘person.json’ в коде ниже):

 {
  "firstName": "Sherlock",
  "lastName": "Holmes",
  "language": 1,
  "addresses": [
    {
      "streetNumber": "221B",
      "street": "Baker Street",
      "city": "London"
    }
  ]
}
  

Это пример того, что следует считать недопустимым (‘no_person.json’ в коде ниже):

 {
  "name": "eggs",
  "colour": "white"
}
  

И это код, который я использовал для проверки:

 from json import load
from jsonschema import Draft7Validator, exceptions

with open('schema.json') as f:
    schema = load(f)
with open('person.json') as f:
    person = load(f)
with open('no_person.json') as f:
    no_person = load(f)

validator = Draft7Validator(schema)
try:
    validator.validate(person)
    print("person.json is valid")
except exceptions.ValidationError:
    print("person.json is invalid")
try:
    validator.validate(no_person)
    print("no_person.json is valid")
except exceptions.ValidationError:
    print("no_person.json is invalid")
  

Результат:
person.json is valid
no_person.json is valid

Я ожидал, что no_person.json будет недействительным. Что можно сделать, чтобы только такие данные, как person.json, были успешно проверены? Большое вам спасибо за вашу помощь, я очень новичок в этом (потратил годы на поиск ответа).

Ответ №1:

Это рабочая схема, и обратите внимание на «требуется» (когда такого ключа нет — если поле не получает, оно просто пропускается):

 {
  "type": "object",
  "properties": {
      "firstName": {
        "type": "string"
      },
      "lastName": {
        "type": "string"
      },
      "language": {
        "type": "integer"
      },
      "addresses": {
        "type": "array",
        "items": {
            "type": "object",
            "properties": {
              "streetNumber": {
                "type": "string"
              },
              "street": {
                "type": "string"
              },
              "city": {
                "type": "string"
              }
            },
            "required": [
              "streetNumber",
              "street",
              "city"
           ]
        }
      }
  },
  "required": [
    "firstName",
    "lastName",
    "language",
    "addresses"
  ]
}

  

У меня есть:

 person.json is valid
no_person.json is invalid
  

Если у вас самая сложная структура ответа (массив объектов, которые содержат объекты и т.д.), Дайте мне знать

Комментарии:

1. Спасибо за вашу помощь и извините, что приняли ваш ответ так поздно! Проблема заключалась в том, что я не мог просто изменить схемы вручную. В итоге я написал простой скрипт, который «исправляет» схемы, добавляя все существующие свойства в «требуемые» массивы, что, как вы продемонстрировали, устранило проблему. Не очень хорошее решение, но в то время оно работало.