【问题标题】:How to force object key name in array如何强制数组中的对象键名
【发布时间】:2018-05-11 20:55:58
【问题描述】:

我正在使用 YAML 来标记一些公式并使用 JSON 模式来提供参考模式。 YAML 的一个示例可能是:

formula: # equates to '5 + (3 - 2)'
  add:
    - 5
    - subtract: [3, 2]

虽然我已经弄清楚如何使公式的直接子对象(本例中为 "add")具有正确的键名和类型(使用 "required"s 的 "oneOf"array)。我不确定如何确保数组的对象 ("subtract") 同样使用特定的键名。

到目前为止,我可以使用以下方法确保类型。但是使用这种方法,只要使用的对象匹配减法type,就可以任意键名,不限于subtract:

"definitions: {
    "add": {
        "type": "array",
        "minItems": 2,
        "items": {
            "anyOf": [
                { "$ref": "#/definitions/value"}, # value type is an integer which allows for the shown scalar array elements
                { "$ref": "#/definitions/subtract" }
                // other operation types
            ]
        }
    },
    "subtract": {
        "type": "array",
        "minItems": 2,
        "maxItems": 2,
        "items": {
            "anyOf": [
                { "$ref": "#/definitions/value"},
                { "$ref": "#/definitions/add" }
                // other operation types
            ]
        }
    }
    // other operation types
}

如何引入限制,使数组中对象的键匹配特定名称,同时仍然允许标量元素?

【问题讨论】:

    标签: yaml jsonschema


    【解决方案1】:

    听起来你想要的是递归引用。

    通过创建一个新定义,即 oneOf 操作和 value,然后允许项目随后引用回新定义,您就有了递归引用。

    "definitions: {
        "add": {
            "type": "array",
            "minItems": 2,
            "items": { "$ref": "#/definitions/operations_or_values"},
        },
        "subtract": {
            "type": "array",
            "minItems": 2,
            "maxItems": 2,
            "items": { "$ref": "#/definitions/operations_or_values"},
        }
        // other operation types
        "operations_or_values": {
          "anyOf": [
            { "$ref": "#definitions/add" },
            { "$ref": "#definitions/subtract" },
            { "$ref": "#definitions/value" },                 # value type is an integer which allows for the shown scalar array elements
            { "$ref": "#definitions/[OTHERS]" },
          ]
        }
    }
    

    我还没有时间对此进行测试,但我相信它会是或接近于您所需要的。让我知道它是否不起作用。我可能没有完全理解这个问题。

    【讨论】:

      【解决方案2】:

      多么有趣的问题啊!这种非常简洁的模式可以表达任何表达式。

      {
        "type": ["object", "number"],
        "propertyNames": { "enum": ["add", "subtract", "multiply", "divide"] },
        "patternProperties": {
          ".*": {
            "type": "array",
            "minItems": 2,
            "items": { "$ref": "#" }
          }
        }
      }
      

      【讨论】:

        【解决方案3】:

        所以我最终做的是扩展我已经使用 "required" 的 '"oneOf"array 的想法,添加一个 "anyOf"

        因此,运算符模式现在是:

        "definitions": {
            "add": {
                "type": "array",
                "minItems": 2,
                "items": {
                    "anyOf": [
                        { "$ref": "#/definitions/literal" }, // equates to a simple YAML scalar
                        { "$ref": "#/definitions/constant" },
                        { "$ref": "#/definitions/variable" },
                        {
                            "type": "object",
                            "oneOf": [
                                { "required": ["add"] },
                                { "required": ["subtract"] }
                                // more operator names
                            ],
                            "properties": {
                                "add": { "$ref": "#/definitions/add" },
                                "subtract": { "$ref": "#/definitions/subtract" }
                                // more operator type references
                            }
                        }
                    ]
                }
            },
            // more definitions
        }
        

        这可以重构为更容易应用于不同运算符的东西,如下所示:

        "definitions": {
            "operands": {
                "literal": { "type": "number" }, // equates to a simple YAML scalar
                "constant": {
                    "type": "object",
                    "properties": {
                        "value": { "type": "number" }
                    },
                    "required": [ "value" ]
                },
                "variable": {
                    "type": "object",
                    "properties": {
                        "name": { type": "string" },
                        "type": { "type": "string" }
                    },
                    "required": [ "name", "type" ]
                }
            }
            "operators": {
                "add": {
                    "type": "array",
                    "minItems": 2,
                    "items": { "$ref": "#/definitions/anyOperandsOrOperators" }
                },
                "subtract": {
                    "type": "array",
                    "minItems": 2,
                    "maxItems": 2,
                    "items": { "$ref": "#/definitions/anyOperandsOrOperators" }
                }
                // more operator types
            },
            "anyOperator": {
                "type": "object",
                "oneOf": [
                    { "required": ["add"] },
                    { "required": ["subtract"] }
                    // more operator names
                ],
                "properties": {
                    "add": { "$ref": "#/definitions/operators/add" },
                    "subtract": { "$ref": "#/definitions/operators/subtract" }
                    // more operator type references
                }
            },
            "anyOperandsOrOperators":
            {
                "anyOf": [
                    { "$ref": "#/definitions/operands/literal" },
                    { "$ref": "#/definitions/operands/constant" },
                    { "$ref": "#/definitions/operands/variable" },
                    { "$ref": "#/definitions/anyOperator"}
                ]
            }
        }
        

        这意味着运算符的 YAML 可以如下所示

                            \/mapping   \/mapping
        add:[ 5, subtract:[ *constantA, *variableB ] ]
        scalar^  ^mapping with specific name
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-26
          • 2018-05-17
          • 2021-05-20
          • 1970-01-01
          • 2012-01-12
          • 1970-01-01
          • 2021-06-30
          • 1970-01-01
          相关资源
          最近更新 更多