Условная проверка схемы JSON для определенного атрибута объекта в массиве - PullRequest
1 голос
/ 27 сентября 2019

Что я хочу сделать с помощью AJV - проверка схемы JSON или пользовательские ключевые слова (желательно, я бы пошел с этим): Массив может иметь 1 или 2 объекта JSON с типом «admin» и «guest».Объект "type": "guest" всегда будет присутствовать, а объект "type": "admin" является необязательным.

Дополнительные примечания:

- Сам объект может содержать дополнительные атрибуты и быть вложеннымобъекты, в будущем

-Другие допустимые перечисления: superadmin, admin, user и guest

-Последовательность типов в массиве: superadmin, admin, user и guest.Можно ли проверить последовательность?(хотя это и необязательно)

- Объект типа «гость» всегда будет там, и будет объект уникального типа.При повторном возникновении любого типа объекта (например, superadmin, admin, user и guest) возникает ошибка

// Вот схема:

{
"type": "object",
"properties": {
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "type": { "enum": ["guest", "admin"]
    },
    "rights": {"type": "string"},
    "hyperLink": {"type": "string", "format": "uri"}
    }
  }
  }
}

Мне нужно добавить 'checkTypeAndValue'где-нибудь в json флаг, чтобы я мог получить полный объект JSON и соответствующие атрибуты для программной проверки?

const checkTypeAndValue = function (schema, completeJSONObj) {
 //
};

ajv.addKeyword('checkTypeAndValue', {
  validate: checkTypeAndValue,
  errors: true
});

, и вот несколько допустимых и недействительных примеров:

/Valid 1: As type is 'admin' and so 'rights' SHOULD NOT be in 'guest' object
{
  [
    {
      "type":"admin",
      "hyperLink": "http://www.someguest.com",
      "rights":"all"
    },
    {
      "type":"guest",
      "hyperLink": "http://www.someadmin.com"
    }
  ]
}

//Valid 2: You can have a SINGLE 'guest' object. 'admin' object is not required all the time
{
  [
    {
      "type":"guest",
      "hyperLink": "http://www.someadmin.com",
      "rights": "limited" //MANDATORY or REQUIRED Attribute
    }
  ]
}

//InValid
{
  [
    {
      "type":"admin",
      "hyperLink": "http://www.someguest.com",
      "rights":"all"
    },
    {
      "type":"guest",
      "hyperLink": "http://www.someadmin.com",
      "rights":"limited"
      //Error ==> As rights=all is there in 1st object, you cannot set 'rights' to any value including blank even having 'rights' attribute is not valid.
    }
  ]
}

Вот условие if else, с которым мне нужно разобраться:

//Assuming admin object exist with rights....
if( type == admin && rights != ""){
  if(type == guest && rights attribute is there && rights != ""){
    //The 'guest' object will always be there....
    //error: guest 'rights' cannot have a value if type is 'admin' and rights is 'all' or any other value.
  }
}else{
   //Assuming mandatory guest object exist with rights....
   if(guest.rights does not exist OR guest.rights == "")
    //Error: 'rights' is MANDATORY attribute in guest block and error if its empty
   else 
    //Everything is fine
}

Также есть ли способ, с помощью которого мы можем проверить в массиве, что будет только одна пара объектов определенного типа?Например: только один тип «гость», «администратор».Ошибка, если существует несколько типов 'guest' или 'admin'

// Полный пример

{
  [
    {
      "type":"superadmin",
      "hyperLink": "http://www.superadmin.com"      
    },
    {
      "type":"admin",
      "hyperLink": "http://www.admin.com",
      "rights":"all"
    },
    {
      "type":"user",
      "hyperLink": "http://www.user.com"
    },
    {
      "type":"guest",
      "hyperLink": "http://www.guest.com"
    }
  ]
}

1 Ответ

1 голос
/ 27 сентября 2019

Может показаться немного сложным сделать это со схемой JSON, но это возможно.

Вы должны быть в состоянии условно проверить отрицательное условие.

Итак, вам понадобитсяиспользовать комбинацию if и then, с not.

Сначала условие: если есть пользователь с правами администратора.Используя if, мы можем затем условно применить правило дальнейшей проверки.

Затем проверка: у гостевого пользователя не может быть rights.

then, когда проходит ifПроверка.Затем нам нужно отменить проверку того, что guest имеет rights, используя not.

. Вы можете увидеть, что это правильно провалилось при проверке на примере ожидаемых неверных данных JSON, которые вы предоставили, используя https://jsonschema.dev (ссылка предварительно загружена с этой схемой и предоставленными вами данными экземпляра. В браузере используется AJV.)


Обновление: я обновил схему, чтобы удовлетворить ваши дополнительные требования.Я также обновил демонстрационную ссылку выше.

Схема теперь позволяет администратору иметь права только при наличии администратора, и никакой другой тип пользователя не может иметь права при наличии администратора.Также один элемент в массиве должен иметь права (как вам требуется).

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "if": {
    "contains": {
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "admin"
        }
      }
    }
  },
  "then": {
    "not": {
      "contains": {
        "required": [
          "type",
          "rights"
        ],
        "properties": {
          "type": {
            "not": {
              "const": "admin"
            }
          }
        }
      }
    }
  },
  "contains": {
    "type": "object",
    "required": ["rights"]
  },
  "items": {
    "type": "object",
    "properties": {
      "type": {
        "enum": [
          "guest",
          "admin"
        ]
      },
      "rights": {
        "type": "string"
      },
      "hyperLink": {
        "type": "string",
        "format": "uri"
      }
    }
  }
}
...