Сценарий JSON Schema if-else сложный сценарий - PullRequest
0 голосов
/ 30 марта 2019
    {
        "policyHolder": {
            "fullName": "A"
        },
        "traveller": [
            {
                "fullName": "B",
                "relationship": "Spouse"
            },
            {
                "fullName": "A",
                "relationship": "My Self"
            }
        ]
    }

В приведенном выше json я хочу подтвердить, что

  • if "relationship" = "My Self", тогда fullName должно соответствовать fullName в policyHolder
  • поле relationship должен существовать в массиве traveller, иначе json недействителен

Я пытался создать схему json с if-else, allOf и т. Д., Но ничего не работает, что может сделать эти проверкино не в состоянии.Пожалуйста, помогите !!

Схема:

{
    "type": "object",
    "required": [
        "policyHolder",
        "traveller",
    ],
    "properties": {
        "policyHolder": {
            "$id": "#/properties/policyHolder",
            "type": "object",
            "required": [
                "fullName"
            ],
            "properties": {
                "fullName": {
                    "$id": "#/properties/policyHolder/properties/fullName",
                    "type": "string",
                }
            }
        },
        "traveller": {
            "$id": "#/properties/traveller",
            "type": "array",
            "minItems": 1,
            "items": {
                "$id": "#/properties/traveller/items",
                "type": "object",
                "properties": {
                    "fullName": {
                        "$ref": "#/properties/policyHolder/properties/fullName"
                    },
                    "relationship": {
                        "$id": "#/properties/traveller/items/properties/relationship",
                        "type": "string",
                    }
                },
                "required": [
                    "fullName",
                    "relationship"
                ],
                }
            }
        }
    }```

Ответы [ 2 ]

1 голос
/ 31 марта 2019

В настоящее время это невозможно сделать с помощью схемы JSON. Все ключевые слова JSON Schema могут работать только с одним значением за раз. Есть предложение по добавлению ключевого слова $data, которое позволило бы выполнять такую ​​проверку, но я не думаю, что оно будет принято. $data будет работать как $ref, за исключением того, что он ссылается на проверяемый JSON, а не на схему.

Вот как бы вы решили свою проблему с $data.

{
  "type": "object",
  "properties": {
    "policyHolder": {
      "type": "object",
      "properties": {
        "fullName": { "type": "string" }
      }
    },
    "traveler": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "fullName": { "type": "string" },
          "relationship": { "type": "string" }
        },
        "if": {
          "properties": {
            "relationship": { "const": "My Self" }
          }
        },
        "then": {
          "properties": {
            "fullName": { "const": { "$data": "#/policyHolder/fullName" } }
          }
        }
      }
    }
  }
}

Без $data вам придется выполнить эту проверку в коде или изменить структуру данных таким образом, чтобы в этом не было необходимости.

1 голос
/ 31 марта 2019

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

Во-вторых, я бы предложил вам извлечь некоторые из ваших подсхем в определения, а не пытаться копаться с идентификаторами.Идентификаторы, как правило, более полезны, если вы ссылаетесь на них из других документов или используете короткие (например, одно слово) идентификаторы.Определение идентификатора в качестве его местоположения в документе является излишним;большинство процессоров будут обрабатывать это автоматически.

{
  "type": "object",
  "required": [
    "policyHolder",
    "traveller",
  ],
  "definitions": {
    "person": {
      "type": "object"
      "properties": {
        "fullName": {"type": "string"}
      },
      "required": ["fullName"]
    },
    "relationship": { "enum": [ ... ] }   // list possible relationships
  },
  "properties": {
    "policyHolder": { "$ref": "#/definitions/person" },
    "traveller": {
      "type": "array",
      "minItems": 1,
      "items": {
        "allOf": [
          { "$ref": "#/definitions/person" },
          {
            "properties": {
              "relationship": { "$ref": "#/definitions/relationship" }
            },
            "required": ["relationship"]
          }
        ]
      }
    }
  }
}

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

...