использование oneOf с общими элементами в объекте свойства - PullRequest
0 голосов
/ 01 мая 2020

Это файл YAML, который я хочу проверить по схеме JSON. У меня возникли проблемы с получением типа компилятора для поддержки oneOf для выбора одного из компиляторов gnu, intel с общим полем 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"}
      }
    }

  }
}

1 Ответ

1 голос
/ 02 мая 2020

oneOf внутри 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"]
        }
      ]
    }
...