将 oneOf 与 属性 对象中的共享元素一起使用

using oneOf with shared elements in a property object

这是我要使用 JSON 模式验证的 YAML 文件。我在让编译器类型支持 oneOf 到 select 编译器 gnuintel 和共享字段 source 之一时遇到了一些麻烦。我有点困惑 oneOf 如何在属性字段中工作,其中 oneOf 中的每个元素也是 属性。

version: 0.0.1
hello_world_gnu:
  type: compiler
  module:
     - "module purge && module load gcc/4.0"
     - "module purge && module load gcc/6.0"
  compiler:
    source: src/hello.c
    gnu:
      cflags: -O1

hello_world_intel:
  type: compiler
  module:
   -  "module purge &&  module load intel/17"
   -  "module purge &&  module load intel/18"
  compiler:
    source: src/hello.c
    intel:
     cflags: -O1

目前我的架构如下

{
  "$id": "https://buildtesters.github.io/schemas/compiler/compiler-v0.0.1.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "BuildTest Schema for compiler",
  "type": "object",
  "required": ["type", "compiler"],
  "propertyNames": {
    "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
  },
  "properties": {
    "type": {
      "type": "string",
      "pattern": "^compiler$"
    },
    "description": {
      "type": "string"
    },
    "module": {
      "type": "array"
    },
    "compiler": {
      "type": "object",
      "properties": {
        "source": {
          "type": "string"
        },
        "oneOf": [
          {
            "gnu": {
              "$ref": "#/definitions/compiler"
            },
            "intel": {
              "$ref": "#/definitions/compiler"
            }
          }
        ]
      }
    }
  },
  "definitions": {
    "compiler": {
      "type": "object",
      "properties": {
        "cflags": {"type":  "string"},
        "ldflags": {"type": "string"}
      }
    }

  }
}

oneOf inside properties 导致 属性 具有预期的名称。但是由于您不想要 oneOf 属性,因此您必须将其上移至与 properties 相同的级别。也就是说,通常最好在一个地方声明所有属性。然后只描述附加规则什么时候期望什么。

一种可能是声明所有允许的属性,然后使用dependencies来确保不允许同时出现替代属性。

    "compiler": {
      "type": "object",
      "properties": {
        "source": {
          "type": "string"
        },
        "gnu": {
          "$ref": "#/definitions/compiler"
        },
        "intel": {
          "$ref": "#/definitions/compiler"
        }
      },
      "dependencies": {
        "gnu": {
          "not“: { "required": ["intel"] }
        },
        "intel": {
           "not“: { "required": ["gnu"] }
        }
      }
    }

如果需要 gnu/intel 属性,您也可以使用 oneOf,例如像这样:

    "compiler": {
      "type": "object",
      "properties": {
        "source": {
          "type": "string"
        },
        "gnu": {
          "$ref": "#/definitions/compiler"
        },
        "intel": {
          "$ref": "#/definitions/compiler"
        }
      },
      "oneOf": [
        {
          "required": ["gnu"]
        },
        {
          "required": ["intel"]
        }
      ]
    }