如何在不同的属性类型上使用 anyOf?

How to use anyOf on different properties type?

在下面的架构中,我需要 items_listpricevariance 作为必需的键。条件是 pricevariance 可以为 null 也可以不为 null 但两者不能为 null。

虽然我能够实现它,但我很期待是否有任何更短的方法来做到这一点。另外,我不确定 requiredadditionalProperties 键的确切位置。

非常感谢任何帮助。

{
    "type": "object",
    "properties": {
        "items_list": {
            "type": "array",
            "items": {
                "type": "string"
            }
        },
    },
    "anyOf": [
        {
            "properties": {
                "price": {
                    "type": "number",
                    "minimum": 0,
                },
                "variance": {
                    "type": [
                        "number",
                        "null"
                    ],
                    "minimum": 0,
                },
            },
        },
        {
            "properties": {
                "price": {
                    "type": [
                        "number",
                        "null"
                    ],
                    "minimum": 0,
                },
                "variance": {
                    "type": "number",
                    "minimum": 0,
                },
            },
        },
    ],
    # "required": [
    #     "items_list",
    #     "price",
    #     "variance",
    # ],
    # "additionalProperties": False,
}

看来您的判断基本正确。这是放置 required.

的正确位置

使用additionalProperties: false,你还需要在顶层定义propertiesadditionalProperties不能"see through" *Of关键字(applicators)

您可以添加 properties: [prop] : true,但定义所有属性。 您需要这样做,因为 additionalProperties 只知道同一级别的同一架构对象中的 properties

回答问题"can it be shorter?",答案是肯定的。一般的经验法则是永远不要 define 布尔逻辑关键字中的任何内容。仅使用布尔逻辑关键字来添加复合约束。我使用术语 "compound constraint" 表示基于模式中多个值的约束。在这种情况下,复合约束是价格和方差不能都为空。

{
  "type": "object",
  "properties": {
    "items_list": {
      "type": "array",
      "items": { "type": "string" }
    },
    "price": { "type": ["number", "null"], "minimum": 0 },
    "variance": { "type": ["number", "null" ], "minimum": 0 }
  },
  "required": ["items_list", "price", "variance"],
  "additionalProperties": false,
  "allOf": [{ "$ref": "#/definitions/both-price-and-variance-cannot-be-null" }],
  "definitions": {
    "both-price-and-variance-cannot-be-null": {
      "not": {
        "properties": {
          "price": { "type": "null" },
          "variance": { "type": "null" }
        },
        "required": ["price", "variance"]
      }
    }
  }
}

您不仅不必为了 additionalProperties 的正常工作而费尽心思,而且更易于阅读。它甚至符合您对问题的描述,"price and variance may or may not be null" (properties) 但 "both cannot be null" (not (复合约束))。您可以通过内联定义使其更短,但我将其包括在内是为了展示这种技术的表现力,同时仍然比原始模式更短。