jsonschema Чертеж 0.7 обязательных свойств во вложенном объекте в зависимости от значения - PullRequest
0 голосов
/ 18 января 2019

У меня есть файл json с вложенными объектами.

{
    "apiVersion":"0.0.9b",
    "apiDate":"18.01.19",

    "general":{
        "documentType": "invoice",

        "references":{

            "invoiceId":"123",
            "invoiceDate":"01.01.1970",

            "creditNoteId":"123",
            "creditNoteDate":"01.01.1970"
        }
    }
}

Теперь я хотел бы определить, что invoiceId и invoiceDate должны быть обязательными, если documentType - это счет-фактура, а также другой способ - arraound (creditNoteId и Dateтребуется, если documentType является creditNote).Все остальные свойства должны быть необязательными.

Псевдокод:

documentType = invoice
- required: invoiceId, invoiceDate
- optional: creditNoteId, creditNoteDate
documentType = creditNote
- required: creditNoteId, creditNoteDate
- optional: invoiceId, invoiceDate

Если я сохраню все свойства в одном объекте, я найду это рабочее решение:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "apiVersion",
    "apiDate"
  ],
  "properties": {
    "apiVersion": {
      "type": "string",
      "description": "The version of the json file"
    },
    "apiDate": {
      "type": "string",
      "description": "The date when the json version was published"
    },
    "general": {
      "$ref": "#/definitions/general_identifiers"
    }
  },
  "definitions" : {

    "general_identifiers" : {
      "type": "object",
      "required": [
        "documentType"
      ],
      "properties": {
        "documentType": {
          "enum": [
            "invoice",
            "creditNote"
          ]
        },
        "invoiceId": {
          "type": "string"
        },
        "invoiceDate": {
          "type": "string"
        },
        "creditNoteId": {
          "type": "string"
        },
        "creditNoteDate": {
          "type": "string"
        }
      },
      "oneOf": [
        {
          "$comment": "Invoice",
          "properties": {
            "documentType": { "enum": ["invoice"] }
          },
          "required": ["invoiceId", "invoiceDate"]
        },
        {
          "$comment": "CreditNote",
          "properties": {
            "documentType": { "enum": ["creditNote"] }
          },
          "required": ["creditNoteId", "creditNoteDate"]
        }
      ]
    }
  }
}

Есть ли способ отобразить эту зависимость с вложенными объектами, используемыми в вышеупомянутом json?

То, что я уже пробовал, было:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "apiVersion",
    "apiDate"
  ],
  "properties": {
    "apiVersion": {
      "type": "string",
      "description": "The version of the json file"
    },
    "apiDate": {
      "type": "string",
      "description": "The date when the json version was published"
    },
    "general": {
      "$ref": "#/definitions/general_identifiers"
    },
    "references": {
      "type": "object",
      "properties": {
        "invoiceId": {
          "type": "string"
        },
        "invoiceDate": {
          "type": "string"
        },
        "creditNoteId": {
          "type": "string"
        },
        "creditNoteDate": {
          "type": "string"
        }
      },
      "oneOf": [
        {
          "$comment": "Invoice",
          "properties": {
            "documentType": { "enum": ["invoice"] }
          },
          "required": ["invoiceId", "invoiceDate"]
        },
        {
          "$comment": "CreditNote",
          "properties": {
            "documentType": { "enum": ["creditNote"] }
          },
          "required": ["creditNoteId", "creditNoteDate"]
        }
      ]
    }

  },
  "definitions" : {

    "general_identifiers" : {
      "type": "object",
      "required": [
        "documentType"
      ],
      "properties": {
        "documentType": {
          "enum": [
            "invoice",
            "creditNote"
          ]
        }
      }
    }
  }
}

Но с этим я получаю ошибку от https://www.jsonschemavalidator.net

Сообщение: JSON допустим для нескольких схем из 'oneOf'.Допустимые индексы схемы: 0, 1.

Что я пропустил?

Ответы [ 2 ]

0 голосов
/ 21 января 2019

С помощью Jason Desrosiers я наконец нашел решение и для моего вложенного json.

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "required": [
        "apiVersion",
        "apiDate"
    ],
    "anyOf": [
        {
            "properties": {
                "general": {
                    "properties": {
                        "documentType": { "enum": ["invoice"] },
                        "references": {
                            "required": ["invoiceId", "invoiceDate"]
                        }
                    }
                }
            }
        },
        {
            "properties": {
                "general": {
                    "properties": {
                        "documentType": { "enum": ["creditNote"] },
                        "references": {
                            "required": ["creditNoteId", "creditNoteDate"]
                        }
                    }
                }
            }
        }
    ], 
    "properties": {
        "apiVersion": {
            "type": "string",
            "description": "The version of the json file"
        },
        "apiDate": {
            "type": "string",
            "description": "The date when the json version was published"
        },
        "general": {
            "$ref": "#/definitions/general_identifiers",
            "references": {
                "type": "object",
                "properties": {
                    "invoiceId": {
                        "type": "string"
                    },
                    "invoiceDate": {
                        "type": "string"
                    },
                    "creditNoteId": {
                        "type": "string"
                    },
                    "creditNoteDate": {
                        "type": "string"
                    }
                } 
            }
        }
    },
    "definitions" : {
        "general_identifiers" : {
            "type": "object",
            "required": [
                "documentType"
            ],
            "properties": {
                "documentType": {
                    "enum": [
                        "invoice",
                        "creditNote"
                    ]
                }
            }
        }
    }
}
0 голосов
/ 20 января 2019

Ты очень близко. Вам просто нужно поднять oneOf на верхний уровень, чтобы вы могли ссылаться на #/properties/general и #/properties/references из той же схемы.

Кроме того, вы почти всегда хотите использовать anyOf вместо oneOf. oneOf обеспечивает проверку только одной и только одной схемы в списке. Когда схемы являются взаимоисключающими, oneOf просто просит валидатор выполнить ненужную работу.

"anyOf": [
  {
    "properties": {
      "general": {
        "properties": {
          "documentType": { "enum": ["invoice"] }
        }
      },
      "references": {
        "required": ["invoiceId", "invoiceDate"]
      }
    }
  },
  {
    "properties": {
      "general": {
        "properties": {
          "documentType": { "enum": ["creditNote"] }
        }
      },
      "references": {
        "required": ["creditNoteId", "creditNoteDate"]
      }
    }
  }
]
...