【问题标题】:ajv conditional schema validation based on data基于数据的 ajv 条件模式验证
【发布时间】:2017-08-12 01:04:39
【问题描述】:

我想根据另一个字段中的数据为一个字段指定一个正则表达式模式。这可能吗?我试过 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"
            ]
         }
      }
   }
}

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

【问题讨论】:

    标签: json schema ajv


    【解决方案1】:

    有几种方法可以做到这一点

    anyOfpros:draft-04 兼容,cons:错误报告有点冗长 - 如果出现以下情况,您会从两个子模式中得到错误没有匹配):

    {
       "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"]
             }
          }
       }
    }
    

    if/then/elseavailable 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"]
             }
          }
       }
    }
    

    selectavailable in ajv-keywords package优点:比 if/then/else 更简洁,特别是如果有两个以上可能的值,缺点 strong>: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"]
             }
          }
       }
    }
    

    我更喜欢最后一个选项。

    【讨论】:

    • 非常有趣。根据属性之一的值,您将如何处理动态所需属性?
    • 没关系,我想通了,这要归功于 AJV 的出色灵活性。
    • @Vadorequest 你能分享一下你是如何根据属性值做动态所需属性的吗?我正在寻找相同的东西。
    • @SantoshSidnal 我真的不记得了,那是很久以前的事了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2018-10-21
    • 2017-10-23
    • 2020-01-20
    • 2020-02-29
    • 2017-04-29
    • 2017-11-08
    相关资源
    最近更新 更多