json - 基于数据的 ajv 条件模式验证

标签 json schema ajv

我想根据另一个字段的数据为一个字段指定一个正则表达式模式。这可能吗?我试过 switch 和 $data 但不知道如何使用它们。
例如,如果数据如下所示:

{
   "contacts":[
      {
         "mode":"Email",
         "contact":"john.doe@abc.com"
      },
      {
         "mode":"Phone",
         "contact":"111-555-1234"
      }
   ]
}

和架构看起来像:
"$schema":"http://json-schema.org/draft-04/schema#",
   "type":"object",
   "properties":{
      "Contacts":{
         "type":"array",
         "minItems":1,
         "items":{
            "type":"object",
            "properties":{
               "mode":{
                  "type":"string",
                  "enum":[
                     "Email",
                     "Phone"
                  ]
               },
               "contact":{
                  "type":"string",
                  "pattern":"?????"
               }
            },
            "required":[
               "mode",
               "contact"
            ]
         }
      }
   }
}

如何根据模式中的数据设置联系人模式,以便如果模式是电子邮件,它会根据电子邮件格式的正则表达式验证联系人,如果模式是电话,它会根据电话格式的正则表达式验证联系人?我有每个的正则表达式。我需要逻辑来选择其中之一。

最佳答案

有几种方法可以做到

任何 ( 优点 :draft-04 兼容, 缺点 :错误报告有点冗长 - 如果没有匹配,您将从两个子模式中得到错误):

{
   "type": "object",
   "properties": {
      "Contacts": {
         "type": "array",
         "minItems": 1,
         "items": {
            "type": "object",
            "anyOf": [
               {
                  "properties": {
                     "mode": {"enum": ["Email"]},
                     "contact": {
                        "type": "string",
                        "format": "email"
                     }
                  }
               },
               {
                  "properties": {
                     "mode": {"enum": ["Phone"]},
                     "contact": {
                        "type": "string",
                        "pattern": "phone_pattern"
                     }
                  }
               }
            ],
            "required": ["mode", "contact"]
         }
      }
   }
}

如果/那么/其他 ( available in ajv-keywords package 优点 :错误报告更有意义, accepted to be included in draft-07 缺点 :目前不标准):
{
   "type": "object",
   "properties": {
      "Contacts": {
         "type": "array",
         "minItems": 1,
         "items": {
            "type": "object",
            "properties": {
               "mode": {"type": "string", "enum": ["Email", "Phone"]},
               "contact": {"type": "string"}
            },
            "if": {
               "properties": {
                  "mode": {"enum": ["Email"]}
               }
            },
            "then": {
               "properties": {
                  "contact": {"format": "email"}
               }
            },
            "else": {
               "properties": {
                  "contact":  {"pattern": "phone_pattern"}
               }
            }
            "required": ["mode", "contact"]
         }
      }
   }
}

选择 ( available in ajv-keywords package , 优点 : 比 if/then/else 更简洁,特别是如果有两个以上的可能值, 缺点 : not on the standard track yet 支持: ),需要启用 $data 引用和 Ajv v5.xx):
{
   "type": "object",
   "properties": {
      "Contacts": {
         "type": "array",
         "minItems": 1,
         "items": {
            "type": "object",
            "properties": {
               "mode": {"type": "string"},
               "contact": {"type": "string"}
            },
            "select": { "$data": "0/mode" },
            "selectCases": {
               "Email": {
                  "properties": {
                     "contact": {"format": "email"}
                  }
               },
               "Phone": {
                  "properties": {
                     "contact": {"pattern": "phone_pattern"}
                  }
               }
            },
            "selectDefault": false,
            "required": ["mode", "contact"]
         }
      }
   }
}

我更喜欢最后一个选项。

关于json - 基于数据的 ajv 条件模式验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42908916/

相关文章:

database - 分析数据模式(在 github 上): dimension & measure

jsonschema - 在 anyOf 中为 JSON Schema 嵌套 oneOf

java - 解析 json 时 GSON 中的数字格式异常

python - 如何编写和阅读日期时间词典

javascript - 如何使用两个数组创建 json 数据并将其返回给 ajax

sql-server - 如何为用户定义字段(UDF)设计数据库?

ios - 处理 JSON 响应中的字符串或整数

node.js - 设置选择 : false to subdocuments array at mongoose

javascript - Objection.js 忽略对无法识别的属性类型的验证?

javascript - 使用 AJV 验证针对 JSON 架构的 API 响应