JSON 模式 - 在嵌套对象中重用基本/根属性

问题描述 投票:0回答:1

所以我有以下 JSON 结构:

{
  "attributeA": "...",
  "attributeB": "...",
  "attributeC": "...",
  "attributeD": "...",
  "innerObjA": {
    "attributeA": "...",
    "attributeB": "...",
    "attributeC": "...",
    "exclusiveFieldX": "...",
  },
  "innerObjB": {
    "attributeA": "...",
    "attributeB": "...",
    "attributeC": "...",
    "exclusiveFieldY": "..."
  }
}

我正在尝试构建一个 JSON 模式来验证结构。

到目前为止我有这样的事情:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://example.com/product.schema.json",
    "title": "Product",
    "description": "A product in the catalog",
    "type": "object",
    "properties": {
        "attributeA": {
            "type": "String"
        },
        "attributeB": {
            "type": "String"
        },
        "attributeC": {
            "type": "String"
        },
        "attributeD": {
            "type": "String"
        },
        "innerObjA": {
            "type": "object",
            "properties": {
                "attributeA": {
                    "type": "String"
                },
                "attributeB": {
                    "type": "String"
                },
                "attributeC": {
                    "type": "String"
                },
                "exclusiveFieldX": {
                    "type": "String"
                }
            }
        },
        "innerObjB": {
            "type": "object",
            "properties": {
                "attributeA": {
                    "type": "String"
                },
                "attributeB": {
                    "type": "String"
                },
                "attributeC": {
                    "type": "String"
                },
                "exclusiveFieldY": {
                    "type": "String"
                }
            }
        }
    },
    "$defs": {
        "common_inner_fields": {}
    }
}

我相信“common_inner_fields”可以用来存储 3 个公共字段,如下所示:

    "$defs": {
        "base_properties_platform": {
            "attributeA": {
                "type": "String"
            },
            "attributeB": {
                "type": "String"
            },
            "attributeC": {
                "type": "String"
            }
        }
    }

但我不知道是否可以将其与专有字段结合起来:

        "innerObjA": {
            "type": "object",
            "properties": {
                "$ref": "#/$defs/base_properties_platform",
                "exclusiveFieldX": {
                    "type": "String"
                }
            }
        },
        "innerObjB": {
            "type": "object",
            "properties": {
                "$ref": "#/$defs/base_properties_platform",
                "exclusiveFieldY": {
                    "type": "String"
                }
            }
        }

如何实现这样的组合?

jsonschema
1个回答
0
投票

您走在正确的轨道上,您需要考虑的一件事是正在使用的 JSON Schema 的草稿版本。有些行为随着时间的推移而改变。

我看到您的示例正在使用 Draft2020-12,因此我将重点关注该示例,但为了完整性提供早期的行为

JSON 架构草案 - 2020-12

$ref
可以在任何级别具有同级定义,因此只需定义
$ref
和附加
properties
定义即可。

在您的示例中,您在

$ref
定义中有
properties
,它应该是
properties
的兄弟。

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://example.com/product.schema.json",
    "title": "Product",
    "description": "A product in the catalog",
    "$ref": "#/$defs/base_properties_platform",
    "type": "object",
    "properties": {
        "attributeD": {
            "type": "string"
        },
        "innerObjA": {
            "$ref": "#/$defs/base_properties_platform",
            "type": "object",
            "properties": {
                "exclusiveFieldX": {
                    "type": "string"
                }
            }
        },
        "innerObjB": {
            "$ref": "#/$defs/base_properties_platform",
            "type": "object",
            "properties": {
                "exclusiveFieldY": {
                    "type": "string"
                }
            }
        }
    },
    "$defs": {
        "base_properties_platform": {
            "attributeA": {
                "type": "string"
            },
            "attributeB": {
                "type": "string"
            },
            "attributeC": {
                "type": "string"
            }
        }
    }
}

JSON 架构草案 04 - 目前

之前的草案要求使用

allOf
来封装
$ref
properties
定义,因为在 2020-12 草案之前,不允许兄弟姐妹使用
$ref
。如果您从旧版本迁移,该规范仍然向后兼容以使用此设计。

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "https://example.com/product.schema.json",
    "title": "Product",
    "description": "A product in the catalog",
    "allOf": [
        {
            "$ref": "#/definitions/base_properties_platform"
        },
        {
            "type": "object",
            "properties": {
                "attributeD": {
                    "type": "string"
                },
                "innerObjA": {
                    "allOf": [
                        {
                            "$ref": "#/definitions/base_properties_platform"
                        },
                        {
                            "type": "object",
                            "properties": {
                                "exclusiveFieldX": {
                                    "type": "string"
                                }
                            }
                        }
                    ]
                },
                "innerObjB": {
                    "allOf": [
                        {
                            "$ref": "#/definitions/base_properties_platform"
                        },
                        {
                            "type": "object",
                            "properties": {
                                "exclusiveFieldY": {
                                    "type": "string"
                                }
                            }
                        }
                    ]
                }
            }
        }
    ],
    "definitions": {
        "base_properties_platform": {
            "attributeA": {
                "type": "string"
            },
            "attributeB": {
                "type": "string"
            },
            "attributeC": {
                "type": "string"
            }
        }
    }
}

附注JSON 模式原始类型始终为小写。 字符串对象数组数字整数布尔值null

© www.soinside.com 2019 - 2024. All rights reserved.