如何验证可以包含不同类型对象的项目的数组

时间:2019-05-28 11:17:55

标签: jsonschema python-jsonschema

我有一个架构,其中有一个数组(在传输对象内部),该数组可能具有两个选项(A或B)之一。

我已经附加了模式和样本数据(实际上应该经过验证,当它应该抛出错误时)。

在translateDataDef->项下,我尝试了“ anyOf”,“ oneOf”,“ type”,即使数据不匹配(数据包含未在任何地方定义的optionC),它们也会产生无错误的消息

我正在使用jsonschema python库。我也尝试过在https://www.jsonschemavalidator.net/中使用此模式+数据,但结果相同。

模式:

{
  "definitions": {
    "optionADef": {
      "type": "object",
      "properties": {
        "pattern": {
          "type": "string",
          "enum": [
            "random",
            "fixed"
          ]
        },
        "startbyte": {
          "type": "number"
        }
      },
      "required": [
        "startbyte"
      ],
      "additionalProperties": false
    },
    "optionBSubItemDef": {
      "type": "object",
      "properties": {
        "value": {
          "type": "number",
          "minimum": 0
        }
      }
    },
    "optionBSettingsDef": {
      "type": "object",
      "properties": {
        "sequence": {
          "type": "number",
          "minimum": 0
        }
      }
    },
    "optionBDataDef": {
      "type": "object",
      "properties": {
        "subitem": {
          "ref": "#/definitions/optionBSubItemDef"
        }
      }
    },
    "optionBDef": {
      "type": "object",
      "properties": {
        "_data": {
          "ref": "#/definitions/optionBDataDef"
        },
        "_settings": {
          "$ref": "#/definitions/optionBSettingsDef"
        }
      },
      "required": [
        "_data"
      ],
      "additionalProperties": false
    },
    "transmitDataDef": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1,
      "items": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "optionA": {
                "ref": "#/definitions/optionADef"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "optionB": {
                "ref": "#/definitions/optionBDef"
              }
            },
            "additionalProperties": false
          }
        ]
      }
    },
    "transmitSettingsDef": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number",
          "minimum": 0,
          "maximim": 8
        }
      }
    },
    "transmitDef": {
      "type": "object",
      "properties": {
        "_data": {
          "ref": "#/definitions/transmitDataDef"
        },
        "_settings": {
          "$ref": "#/definitions/transmitSettingsDef"
        }
      },
      "required": [
        "_data"
      ],
      "additionalProperties": false
    },
    "bundleDef": {
      "type": "object",
      "properties": {
        "transmit": {
          "$ref": "#/definitions/transmitDef"
        }
      },
      "oneOf": [
        {
          "required": [
            "transmit"
          ]
        }
      ],
      "additionalProperties": false
    }
  },
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "bundle": {
      "$ref": "#/definitions/bundleDef"
    }
  },
  "required": [
    "name",
    "bundle"
  ]
}

样本数据:

{
  "name": "test1",
  "bundle": {
    "transmit": {
      "_settings": {
        "length": 0
      },
      "_data": [
        {
          "optionC": {
            "_settings": {
              "sequence": 150
            },
            "data1": [
              {
                "subitem": {
                  "value": 100
                }
              }
            ]
          }
        }
      ]
    }
  }
}

我希望验证捕获“ optionC”并将其标记为错误。如果我有optionB而不是optionC,则希望它将“ data1”标记为无效项。

1 个答案:

答案 0 :(得分:1)

您采用正确的方法。我使用https://jsonschema.dev

使用以下架构和实例对此进行了验证

模式:

{
  "properties": {
    "_data": {
      "type": "array",
      "items" : {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "inline": true
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "rewrite": true
            },
            "additionalProperties": false
          }
        ]
      }
    }
  }
}

实例:

{
  "_data": [
    {
      "optionC": {
        "_settings": {
          "sequence": 150
        },
        "data1": [
          {
            "subitem": {
              "value": 100
            }
          }
        ]
      }
    }
  ]
}

除了您使用“ anyOf”以外,还有其他问题,这是正确的。

这实际上是更简单的事情...

您已经在很多地方在模式中使用了“ ref”而不是“ $ ref”。未知关键字会被忽略,因此您的引用无效。

如果有什么安慰的话,我花了很长时间调试!