如何在JSON Schema中实现深层对象唯一性校验?
Great question! Let's break this down. The reason your test data passes validation right now is that uniqueItems: true only checks if entire objects are identical. Since your two entries have different ioFunction values, they're considered distinct items—even though their ioPosition and ioType are duplicates.
Now, the good news: you can enforce uniqueness on specific deep field combinations in your Schema, though how you do it depends on whether your validator supports certain extensions. Here's how to handle it:
Option 1: Use the $data keyword (works with your validator)
Many JSON Schema validators (including the one you're using) support the $data extension, which lets you reference values from the instance being validated. We can use this to ensure no two items share the same ioPosition + ioType pair.
Update your modulIOs schema by adding an extra rule to the items' allOf block:
{ "$schema": "http://json-schema.org/draft-06/schema#", "type": "object", "required": ["modulIOs"], "properties": { "modulIOs": { "type": "array", "items": { "allOf": [ { "type": "object", "required": ["ioPosition", "ioType", "ioFunction"], "additionalProperties": false, "properties": { "ioPosition": { "type": "integer" }, "ioType": { "type": "string", "enum": ["in", "out"] }, "ioFunction": { "type": "string" } } }, // New rule to enforce unique (ioPosition + ioType) pairs { "not": { "contains": { "allOf": [ { "properties": { "ioPosition": { "const": { "$data": "1/ioPosition" } } }, "required": ["ioPosition"] }, { "properties": { "ioType": { "const": { "$data": "1/ioType" } } }, "required": ["ioType"] }, // Exclude the current item from the check { "not": { "$ref": "#" } } ] } } } ] } } } }
Here's what this does:
- For each item in the
modulIOsarray, it checks if the array contains another item (not { "$ref": "#" }excludes the current item) that has the sameioPosition(via$data: "1/ioPosition") and sameioType. - If such a duplicate exists, the
notkeyword will make validation fail.
When you test your sample data with this schema, it will correctly reject the duplicate (1, "in") pair.
Option 2: Pure Draft-06 Standard (no extensions)
If you need to stick strictly to the official Draft-06 spec (without relying on non-standard extensions like $data), there's no built-in way to enforce this kind of field-combination uniqueness in the schema itself. Draft-06 doesn't have a mechanism to reference values from the instance within the schema rules.
In this case, you'll have to handle the uniqueness check in your application code after the initial JSON Schema validation passes.
内容的提问来源于stack exchange,提问作者iLuvLogix

