在子模式中引用父模式以进行JSON模式验证

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

我正在研究JSON模式,我不确定我是否正确设计了这个并且会感谢任何建议。

所以我有一个名为“Task.json”的父对象,它引用了一个名为“Data.json”的内部对象。现在我需要一种方法来验证模式,以便“Data.json”的必需属性根据“Task.json”的属性而变化。例如,如果Task.json包含“action = create”,那么我们希望data.json中的属性为“a”,“b”或“c”,而“action = update”应为“a”,“d” ,“e”。我不确定如何在data.json中引用父对象(action),以便能够根据“action”参数指定有效属性。

例:

Task.json

{
   "oneOf":[
      {
         "action":"create",
         "data":"data.json"
      },
      {
         "action":"update",
         "data":"data.json"
      }
   ]
}

Data.json

      {
   "properties":{
      "a":{

      },
      "b":{

      },
      "d":{

      },
      "e":{

      }
   },
   "oneOf":[
      {
         "#/action":{
            "enum":[
               "create"
            ]
         },
         "required":[
            "a",
            "b",
            "c"
         ]
      },
      {
         "#/action":{
            "enum":[
               "update"
            ]
         },
         "required":[
            "a",
            "d",
            "e"
         ]
      }
   ]
}
json jsonschema json-schema-validator
2个回答
0
投票

您可以使用$ref关键字引用子模式。你的案子表达起来有点复杂,但绝对可行。根据您的使用案例的细节,有一些方法可以简化。我在这里展示了最灵活的设计。

{
  "type": "object",
  "properties": {
    "action": { "enum": ["create", "update", "delete"] },
    "data": {
      "type": "object",
      "properties": {
        "a": {},
        "b": {},
        "d": {},
        "e": {}
      }
    }
  },
  "allOf": [
    { "$ref": "#/definitions/action-create-implies-abc" },
    { "$ref": "#/definitions/action-update-implies-ade" }
  ],
  "definitions": {
    "action-create-implies-abc": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/action-create" } },
        {
          "properties": {
            "data": { "required": ["a", "b", "c"] }
          },
          "required": ["data"]
        }
      ]
    },
    "action-update-implies-ade": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/action-update" } },
        {
          "properties": {
            "data": { "required": ["a", "d", "e"] }
          },
          "required": ["data"]
        }
      ]
    },
    "action-create": {
      "properties": {
        "action": { "enum": ["create"] }
      },
      "required": ["action"]
    },
    "action-update": {
      "properties": {
        "action": { "enum": ["update"] }
      },
      "required": ["action"]
    }
  }
}

0
投票

谢谢杰森!你的榜样很棒,让我重新思考原始设计。

所以我刚刚添加了另一层,其中Data.json中有一个“MetaData.json”,而“create”需要“Metadata.json”中的“Data.json”和“a”,“b”和“c” “虽然更新只需要”Metadata.json“,但需要”a“,”d“和”e“。在这种情况下,有没有办法在定义/属性的内部指出data.metadata的必需属性是“a”,“b”和“c”?这种设计遵循“更新”操作可能只需要的用例要传递的“metadata.json”。

例:

Data.json

    {
   "properties":{
      "x":{

      },
      "y":{

      },
      "z":{

      },
"metadata": {
      $ref: "metadata.json"
}
   }

Metadata.json

{
   "properties":{
      "a":{

      },
      "b":{

      },
      "d":{

      },
      "e":{

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