You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON Schema验证未触发预期失败的问题及修复方案

JSON Schema验证不生效的问题解决

基础Schema文件:./resources/json-schemas/simple-person.schema

{
  "$id": "http://example.com/json-schemas/simple-person.schema",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Simple Person",
  "type": "object",
  "people": {
    "items": {
      "properties": {
        "name": {
          "type": "string",
          "description": "The person's name."
        },
        "age": {
          "type": "integer",
          "description": "The person's age."
        }
      },
      "required": [
        "name",
        "age"
      ]
    }
  }
}

扩展Schema文件:./extended-person.schema

{
  "$id": "http://example.com/extended-person.schema",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Extended Person",
  "type": "object",
  "allOf": [
    {
      "$ref": "http://example.com/json-schemas/simple-person.schema"
    },
    {
      "people": {
        "items": {
          "properties": {
            "height": {
              "type": "number",
              "description": "The person's height in centimeters."
            },
            "required": [
              "height"
            ]
          }
        }
      }
    }
  ]
}

待验证数据集:./person-dataset.json

{
    "people": [
        {
            "name": "Bob",
            "age": 25,
            "new value": "value"
        }
    ]
}

验证代码

from pathlib import Path

import json

from referencing import Registry, Resource
from referencing.exceptions import NoSuchResource
from jsonschema import Draft202012Validator


def retrieve_from_filesystem(uri: str):
    SCHEMAS = Path("./resources/json-schemas/")

    if uri.startswith("http://example.com/json-schemas/"):
        path = SCHEMAS / Path(uri.removeprefix("http://example.com/json-schemas/"))
    else:
        raise NoSuchResource(ref=uri)

    contents = json.loads(path.read_text())

    return Resource.from_contents(contents)

registry = Registry(retrieve=retrieve_from_filesystem)

schema = json.load(Path("./extended-person.schema").open())
instance = json.load(Path("./person-dataset.json").open())
validator = Draft202012Validator(schema, registry=registry)

validator.validate(instance)

问题描述

预期验证会失败,原因有两点:

  • 数据集中未包含height属性
  • 数据集中存在Schema未定义的new value属性
    但实际验证却通过了,需要修改让此类不符合要求的数据集触发验证失败。

解决方案

1. 修复height必填项的位置错误

扩展Schema中,required: ["height"]被错误地放在了properties内部,导致规则不生效。需要将它移到和properties同级的位置:

修改后的扩展Schema第二个allOf节点:

{
  "people": {
    "items": {
      "properties": {
        "height": {
          "type": "number",
          "description": "The person's height in centimeters."
        }
      },
      "required": [
        "height"
      ]
    }
  }
}

2. 添加禁止额外属性的规则

JSON Schema默认允许对象包含未在properties中定义的属性,需要添加additionalProperties: false来禁止这种情况。

修改基础Schema

在people.items中添加该规则:

{
  "$id": "http://example.com/json-schemas/simple-person.schema",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Simple Person",
  "type": "object",
  "people": {
    "items": {
      "properties": {
        "name": {
          "type": "string",
          "description": "The person's name."
        },
        "age": {
          "type": "integer",
          "description": "The person's age."
        }
      },
      "required": [
        "name",
        "age"
      ],
      "additionalProperties": false
    }
  }
}

修改扩展Schema

同样在第二个allOf节点的people.items中添加该规则:

{
  "$id": "http://example.com/extended-person.schema",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Extended Person",
  "type": "object",
  "allOf": [
    {
      "$ref": "http://example.com/json-schemas/simple-person.schema"
    },
    {
      "people": {
        "items": {
          "properties": {
            "height": {
              "type": "number",
              "description": "The person's height in centimeters."
            }
          },
          "required": [
            "height"
          ],
          "additionalProperties": false
        }
      }
    }
  ]
}

修改完成后,重新运行验证代码,会触发两个验证错误:

  • 缺少必填属性height
  • 存在未定义的额外属性new value

内容的提问来源于stack exchange,提问作者A Simple Programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:14:51