如何通过JSON Schema确保对象属性名唯一?
如何创建强制属性名唯一的JSON Schema
首先要明确核心事实:JSON语法规范本身就禁止对象中出现重复属性名,但绝大多数JSON解析器处理这类不合法JSON时,会直接静默覆盖前面的重复属性,只保留最后出现的那一个。这就导致你用JSON Schema验证时,拿到的已经是解析后去重的对象,Schema根本看不到原始的重复属性,自然无法触发验证失败。
所以,JSON Schema本身没办法直接检测原始JSON文本中的重复属性——它工作在解析后的对象模型层面。要实现你的需求,需要分两步处理:
1. 预处理:检查原始JSON文本的语法合法性
在将JSON字符串解析为对象之前,先对原始文本做语法校验,重点排查是否存在重复属性。
举个简单的Python实现示例,通过遍历JSON token来检测重复键:
import json from json.decoder import JSONDecoder def has_duplicate_keys(raw_json): decoder = JSONDecoder() tokens = list(decoder.raw_decode(raw_json)[1]) key_stack = [] current_keys = set() for token in tokens: if token == '{': key_stack.append(current_keys) current_keys = set() elif token == '}': current_keys = key_stack.pop() elif isinstance(token, str): # 遇到字符串,判断是否是当前对象的键 if len(current_keys) > 0: if token in current_keys: return True current_keys.add(token) return False # 测试示例JSON raw_json = '''{ "property1" : "value1", "property2" : "value2", "property1" : "value3" }''' if has_duplicate_keys(raw_json): print("错误:JSON包含重复属性名") else: # 语法校验通过后,再执行JSON Schema验证 schema = { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "^.*$": {"type": "string"} }, "additionalProperties": false } data = json.loads(raw_json) # 使用jsonschema库完成属性值验证 import jsonschema try: jsonschema.validate(instance=data, schema=schema) print("验证通过") except jsonschema.exceptions.ValidationError as e: print(f"验证失败:{e}")
2. JSON Schema的补充作用
你的原Schema已经能确保所有属性值为字符串,且没有不符合规则的额外属性,但它无法处理重复键问题——因为解析后的对象已经没有重复键了。所以Schema的作用是在通过语法校验后,验证属性值的合法性。
总结:要实现“属性名唯一”的要求,必须在解析前对原始JSON文本做重复键检查,JSON Schema无法单独完成这个任务。
内容的提问来源于stack exchange,提问作者Cliff Pennalligen
相关产品推荐
相关产品推荐

