条件数组对象的JSON模式验证

re

我有两种类型的数据集,包含csv或固定长度的数据。在csv数据中,字段列表只是名称列表,而在固定长度数据中,每个字段由fieldName和fieldLength指定。我需要一个json模式来验证这两种情况,但是在尝试了几种解决方案(包括这些方案)之后,我不确定是否可以完成。也许我对JSON模式的理解还远远不够完善。

json:

{
      "dataset": "csv data",
      "dataFormat": "csv",
      "fieldList": [{
                  "fieldName": "id"
            },
            {
                  "fieldName": "num"
            },
            {
                  "fieldName": "struct"
            }
      ]
}

{
    "dataset": "fixed length",
    "dataFormat": "fixed",
    "fieldList": [{
            "fieldName": "id",
            "fieldLength": 13
        },
        {
            "fieldName": "num"
        },
        {
            "fieldName": "struct"
        }
    ]
}

JSON模式:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "dataset",
    "dataFormat",
    "fieldList"
  ],
  "properties": {
    "dataset": {
      "$id": "#/properties/dataset",
      "type": "string"
    },
    "dataFormat": {
      "$id": "#/properties/dataFormat",
      "type": "string",
      "enum": [
        "csv",
        "fixed"
      ]
    },
    "fieldList": {
      "$id": "#/properties/fieldList",
      "type": "array",
      "additionalItems": true,
      "items": {
        "$id": "#/properties/fieldList/items",
        "type": "object",
        "additionalProperties": true,
        "required": [
          "fieldName"
        ],
        "if": {
          "properties": {
            "dataFormat": {
              "const": "fixed"
            }
          }
        },
        "then": {"items":{
          "required": [
            "fieldLength"
          ]}
        },
        "properties": {
          "fieldName": {
            "$id": "#/properties/fieldList/items/properties/fieldName",
            "type": "string"
          },
          "fieldLength": {
            "$id": "#/properties/fieldList/items/properties/fieldLength",
            "type": "integer"
          }
        }
      }
    }
  }
}

即使在“固定”类型中,只有第一个项目包括必需的fieldLength,两个文档都得到了肯定验证。有什么建议吗?

卡斯滕

模式中有一些可以改进的地方:

  1. if/then是放错了地方。目前,在中if寻找"dataFormat"属性"fieldList" items,却再也找不到。then同样试图强制执行存在"fieldLength"财产"fieldList".items.items(既然"fieldList".itemsobject和不是array,这只会被忽略。
  2. 您应该删除该additionalItems属性。引用json-schema.org

    items为单个模式时,additionalItems关键字是没有意义的,因此不应使用。

  3. 您可以删除该additionalProperties属性,因为其默认值已经是truejson-schema.org的另一句话

    additionalProperties关键字用于控制的额外的东西,那就是,处理properties他们的名字没有在属性关键字列出。默认情况下,允许任何其他属性。

  4. 这些$id属性并没有增加太多价值(并且与较新的草案2019-09不兼容,在该草案中,只能在new$anchor关键字中使用它们)。您可能要忽略这些。

您的主要问题是此处的第一点。您应该可以通过在顶层添加以下内容来实现所需的功能:

"oneOf": [
  {
    "properties": {
      "dataFormat": { "const": "csv" }
    }
  },
  {
    "properties": {
      "dataFormat": { "const": "fixed" },
      "fieldList": {
        "items": {
          "required": ["fieldLength"]
        }
      }
    }
  }
]

完整的架构如下所示:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "dataset",
    "dataFormat",
    "fieldList"
  ],
  "properties": {
    "dataset": {
      "$id": "#/properties/dataset",
      "type": "string"
    },
    "dataFormat": {
      "$id": "#/properties/dataFormat",
      "type": "string",
      "enum": [
        "csv",
        "fixed"
      ]
    },
    "fieldList": {
      "$id": "#/properties/fieldList",
      "type": "array",
      "items": {
        "$id": "#/properties/fieldList/items",
        "type": "object",
        "required": [
          "fieldName"
        ],
        "properties": {
          "fieldName": {
            "$id": "#/properties/fieldList/items/properties/fieldName",
            "type": "string"
          },
          "fieldLength": {
            "$id": "#/properties/fieldList/items/properties/fieldLength",
            "type": "integer"
          }
        }
      }
    }
  },
  "oneOf": [
    {
      "properties": {
        "dataFormat": {
          "const": "csv"
        }
      }
    },
    {
      "properties": {
        "dataFormat": {
          "const": "fixed"
        },
        "fieldList": {
          "items": {
            "required": [
              "fieldLength"
            ]
          }
        }
      }
    }
  ]
}

为了完整起见:您也可以使用if/实现相同的目的then

"if": {
  "properties": {
    "dataFormat": {
      "const": "fixed"
    }
  }
},
"then": {
  "properties": {
    "fieldList": {
      "items": {
        "required": [
          "fieldLength"
        ]
      }
    }
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章