jsonSchema属性は条件付きで必須


96

jsonSchemaでは、required属性を使用して、定義済みフィールドが必須かどうかを示すことができます。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "header": {
            "type": "object",
            "properties": {
                "messageName": {
                    "type": "string"
                },
                "messageVersion": {
                    "type": "string"
                }
            },
            "required": [
                "messageName",
                "messageVersion"
            ]
        }
    },
    "required": [
        "header"
    ]
}

場合によっては、messageVersionフィールドが必須ではないことを希望します。このフィールドの必須性を条件付きにする方法はありますか?


はい、可能です。データのどの情報が必須性をトリガーするでしょうか?
jruizaranguren

@SarveswaranMeenakshiSundaram-私はjsonスキーマのv4のみを使用したことがわかりません
トムレッドファーン

これはバージョン3でまったく可能ですか?
サルベシュ2017年

@SarveswaranMeenakshiSundaram-わかりません。それを試して、私たちに知らせてください!
トムレッドファーン2017年

回答:


260

状況に応じて、いくつかの異なるアプローチがあります。フィールドを条件付きで要求するには、4つの異なる方法が考えられます。

依存関係

dependenciesキーワードは、条件付きのバリエーションであるrequiredキーワード。のForeachプロパティ。プロパティdependenciesが検証されるJSONに存在する場合、そのキーに関連付けられたスキーマも有効である必要があります。 「foo」プロパティが存在する場合、「bar」プロパティは必須です

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependencies": {
    "foo": { "required": ["bar"] }
  }
}

スキーマにrequiredキーワードのみが含まれている場合は、短い形式もあります。

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependencies": {
    "foo": ["bar"]
  }
}

含意

条件がフィールドの値に依存する場合、含意と呼ばれるブール論理の概念を使用できます。「AはBを意味する」とは、Aがtrueの場合、Bもtrueでなければならないことを意味します。含意は「!AまたはB」として表すこともできます。 「foo」プロパティが「bar」と等しくないか、「bar」プロパティが必要です。または、言い換えると、「foo」プロパティが「bar」と等しい場合、「bar」プロパティは必須です。

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "anyOf": [
    {
      "not": {
        "properties": {
          "foo": { "const": "bar" }
        },
        "required": ["foo"]
      }
    },
    { "required": ["bar"] }
  ]
}

「foo」が「bar」と等しくない場合、#/anyOf/0一致と検証は成功します。「foo」が「bar」と等しい場合、#/anyOf/0失敗#/anyOf/1し、anyOf検証が成功するには有効でなければなりません。

列挙型

条件が列挙型に基づいている場合、それはもう少し簡単です。 「foo」は「bar」または「baz」のいずれかです。「foo」が「bar」と等しい場合、「bar」が必要です。「foo」が「baz」と等しい場合、「baz」が必要です。

{
  "type": "object",
  "properties": {
    "foo": { "enum": ["bar", "baz"] },
    "bar": { "type": "string" },
    "baz": { "type": "string" }
  },
  "anyOf": [
    {
      "properties": {
        "foo": { "const": "bar" }
      },
      "required": ["bar"]
    },
    {
      "properties": {
        "foo": { "const": "baz" }
      },
      "required": ["baz"]
    }
  ]
}

If-Then-Else

JSONスキーマ(draft-07)への比較的新しい追加によりifthenおよびelseキーワードが追加されました。 「foo」プロパティが「bar」と等しい場合、「bar」プロパティは必須です

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "if": {
    "properties": {
      "foo": { "const": "bar" }
    },
    "required": ["foo"]
  },
  "then": { "required": ["bar"] }
}

編集12/23/2017:含意セクションが更新され、If-Then-Elseセクションが追加されました。

EDIT 2018年6月4日:バグ修正されたIf-Then-Elseおよび更新シングルトンのためのenumsが使用しますconst


7
@scubbo if-then-elseキーワードのファンではないため、使用を拒否します。ただし、使用する場合は、allOfこれらの3つのキーワードのみを含むで常にラップすることをお勧めします。{ ...other_keywords..., "allOf": [{ "if": ..., "then": ..., "else": ... }], ...more_keywords... }
Jason Desrosiers 2018

2
@ジェイソンなぜファンではないのif...ですか?あなたの答えでこれについての短い意見は完全に正当化されると思います。それとも長い話ですか?
クレイブリッジ、

6
@ClayBridgesコメントセクションはその議論には適切な場所ではありませんが、短いバージョンです。原則として、JSONスキーマのキーワードはステートレスです。キーワード値以外の情報を使用してインスタンスを検証することはできません。ifthenelse彼らはお互いに依存しているため、このルールに違反します。
ジェイソンDesrosiers

3
@GGirard、これは私が知っているJSONスキーマでのこれらのパターンの使用の最良の扱いです。ブール演算は公式に文書化されていますが、残りは単なる計算です。allOf== AND、anyOf== OR、oneOf== XOR、およびnot== NOT。数学関連のリソース(含意など)については、「ブール代数」をグーグルできます。
Jason Desrosiers

2
@AlexeyShrub私はしばらくこれについて書きたいと思っていましたが、他のものに気を取られていました。私は条件付きのアイデアのファンです。それは人々が理解しやすくします。私の反対は、それが3つの別個のステートフルキーワードとして定義された方法にあります(前のコメントを参照)。他のキーワードが従うアーキテクチャプロパティに違反するキーワードがあると、JSONスキーマバリデーターの実装が難しくなり、効率が低下します。条件文がステートレスである別の方法で定義されている場合、私は異論はありません。
Jason Desrosiers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.