简体   繁体   English

jsonschema 验证未按预期返回错误?

[英]jsonschema validation not returning error as expected?

I am using this schema, I was hoping for value-based conditional schema.我正在使用这个模式,我希望有基于值的条件模式。

If app_name is "test" then property name should be required.如果app_name是“test”,那么属性名称应该是必需的。

if app_name if "rest" then property ips should be required.如果app_name如果 "rest" 那么属性ips应该是必需的。

{
    "type": "object",
    "oneOf": [
        {
            "properties": {
                "app_name": {"enum": ["test"]}
            },
            "required": ["name"]
        },
        {
            "properties": {
                "app_name": {"enum": ["rest"]}
            },
            "required": ["ips"]
        },
    ],
    "properties": {
        "name": {"type": "string"},
        "ips": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": True,
            "items": {
                "type": "string",
                "pattern": "[^ ]",
                "minLength": 1,
                "maxLength": 50
            }
        },
        "app_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "enum": [
                "test",
                "rest"
            ]
        }
    },
    "required": [
        "app_name"
    ]
}

I am using following code我正在使用以下代码

formatted_data = {"app_name": "rest", "name": "test data"}
print jsonschema.exceptions.best_match(jsonschema.Draft4Validator(schema).iter_errors(formatted_data))

I got following validation error我收到以下验证错误

'rest' is not one of ['test'] 'rest' 不是 ['test'] 之一

Failed validating 'enum' in schema[0]['properties']['app_name']: {'enum': ['test']}验证架构中的“枚举”失败[0]['properties']['app_name']: {'enum': ['test']}

On instance['app_name']: 'rest'在实例['app_name']:'休息'

I am not sure if schema itself is invalid or there is a problem with library if self.我不确定架构本身是否无效或者库是否存在问题,如果 self.

I am using我在用

python 2.7蟒蛇 2.7

jsonschema 2.6.0 jsonschema 2.6.0

Ok, it seems there's a typo in schema.好的,模式中似乎有错字。 " T rue" instead of " t rue". “T芸香”,而不是“T芸香”。

You've got:你有:

"uniqueItems": True,

while, best to my knowledge, it should be (though it still may depend on schema validator implementation)而据我所知,它应该是(尽管它仍然可能取决于模式验证器的实现)

"uniqueItems": true,

(see: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf section 5 JSON Values and in general https://www.json.org/ - JSON Schema is a JSON document and it conforms to JSON standard) (参见: http : //www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf第 5 节 JSON 值和一般https://www.json.org/ - JSON 模式是一个JSON 文档,符合 JSON 标准)

I've run it through .net online JSON schema validator at https://www.jsonschemavalidator.net/ and it immediately pointed out possible error with schema as above.我已经通过https://www.jsonschemavalidator.net/ 上的.net 在线 JSON 模式验证器运行它,它立即指出了上述模式可能存在的错误。

After typo correction it seems to work perfectly as per your comment from 2018/Nov/16:根据您在 2018 年 11 月 16 日的评论,更正错字后似乎可以完美运行:

As I was passing a value "rest" in app_name.当我在 app_name 中传递一个值“rest”时。 I was expecting an error message "ips" field is required.我期待错误消息“ips”字段是必需的。 – Sachin Aryal – 萨钦·阿里亚尔

Complete schema (please note the "examples" section - only last 2 examples will validate successfully against schema):完整模式(请注意“示例”部分 - 只有最后 2 个示例才能根据模式成功验证):

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "anyOf": [
        {
            "properties": {
                "app_name": {"enum": ["test"]}
            },
            "required": ["name"]
        },
        {
            "properties": {
                "app_name": {"enum": ["rest"]}
            },
            "required": ["ips"]
        },
    ],
    "properties": {
        "name": {"type": "string"},
        "ips": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
                "type": "string",
                "pattern": "[^ ]",
                "minLength": 1,
                "maxLength": 50
            }
        },
        "app_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "enum": [
                "test",
                "rest"
            ]
        }
    },
    "required": [
        "app_name"
    ],
    "examples" : [
      {
        "app_name" : "rest",
      },
      {
        "app_name" : "test",
      },
      {
        "app_name" : "test",
        "ips" : [
         "something1",
         "something2"
        ]
      },
      {
        "app_name" : "rest",
        "name" : "qwerty"
      },
      {
        "app_name" : "test",
        "name" : "qwerty"
      },
      {
        "app_name" : "rest",
        "ips" : [
          "something1",
          "something2"
        ]
      }
    ]
}

Could you correct item in schema and give it a try with your tooling and let us know the result?您能否更正模式中的项目并尝试使用您的工具并让我们知道结果?

On top of that:最重要的是:

If you pass for validation JSON object like:如果您通过验证 JSON 对象,如:

{
  "app_name" : "rest",
  "name" : "qwerty"
},

against your schema, where "oneOf" is used - validator will/should run object against all schemas in "oneOf" array to make sure it matches exactly one of provided schemas.针对您的架构,其中使用了“oneOf” - 验证器将/应该针对“oneOf”数组中的所有架构运行对象,以确保它与提供的架构之一完全匹配。 Thus errors for "oneOf/0/" schema are valid - "app_name" : "rest" doesn't validate against defined enum.因此,“oneOf/0/”模式的错误是有效的 - “app_name”:“rest”不会针对定义的枚举进行验证。 The validator has no clue what you meant by providing specific JSON for validation against schema, so if "allOf" (logical XOR) condition is not satisfied, I'd expect errors from all schemas the JSON was run against within "oneOf" array (even if these seem to be false-positives for you).验证器不知道您通过提供特定的 JSON 以针对模式进行验证是什么意思,因此如果不满足“allOf”(逻辑 XOR)条件,我希望在“oneOf”数组中运行 JSON 的所有模式都会出现错误(即使这些对您来说似乎是误报)。

If some error message is missing, you might want to consider checking with/reporting to lib authors your exact case.如果缺少某些错误消息,您可能需要考虑检查/向库作者报告您的确切情况。

Hope it helped.希望它有所帮助。

UPDATE更新

So it seems you are another one chasing meaningful errors ;-) Yes, that can be a pain when using logical operators.因此,您似乎是另一个追逐有意义错误的人;-) 是的,使用逻辑运算符时可能会很痛苦。

For simple case like above, you can use for draft-07 if-then-else approach, however there's a caveat to it - see REMARK.对于像上面这样的简单情况,您可以使用draft-07 if-then-else方法,但是有一个警告 - 请参阅备注。

Schema first (note how I replaced "anyOf" with two "if-then"):首先是模式(注意我是如何用两个“if-then”替换“anyOf”的):

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "if": {
      "properties": {
        "app_name": {"enum": ["test"]}
      },      
    },
    "then" : { "required": ["name"] },
    "if" :  {
      "properties": {
        "app_name": {"enum": ["rest"]}
      },       
    },
    "then" : { "required": ["ips"]},
    "properties": {
        "name": {"type": "string"},
        "ips": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
                "type": "string",
                "pattern": "[^ ]",
                "minLength": 1,
                "maxLength": 50
            }
        },
        "app_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "enum": [
                "test",
                "rest"
            ]
        }
    },
    "required": [
        "app_name"
    ],
    "examples" : [
      {
        "app_name" : "rest",
      },
      {
        "app_name" : "test",
      },
      {
        "app_name" : "test",
        "ips" : [
         "something1",
         "something2"
        ]
      },
      {
        "app_name" : "rest",
        "name" : "qwerty"
      },
      {
        "app_name" : "test",
        "name" : "qwerty"
      },
      {
        "app_name" : "rest",
        "ips" : [
          "something1",
          "something2"
        ]
      }
    ]
}

REMARK评论

Schema validator jsonschema.net tends to provide exact if-then-else errors in simple cases, when schema in "then" and "else" contains no nested "if-then" and consists of single statement/schema expression.模式验证器 jsonschema.net 在简单情况下倾向于提供精确的 if-then-else 错误,当“then”和“else”中的模式不包含嵌套的“if-then”并且由单个语句/模式表达式组成时。 However, whenever more complex case is structured, you may run into a general error message like: JSON does not match schema from 'then'.但是,每当构建更复杂的案例时,您可能会遇到一般错误消息,例如: JSON 与“then”中的架构不匹配。 or JSON does not match schema from 'else'.JSON 与“else”中的架构不匹配。 without additional details (you'd need to check python output on your own).没有额外的细节(你需要自己检查 python 输出)。 You can work around it to some point by properly shaping dependencies or sub-schemas, but with really complex schema, if you are after detailed error message, you may be facing the limit of validator implementation error messaging anyway.您可以通过适当地塑造依赖项或子模式来解决这个问题,但是对于非常复杂的模式,如果您在查看详细的错误消息,无论如何您都可能面临验证器实现错误消息的限制。 Please see also alternative schema 2 as an example in here: https://stackoverflow.com/a/53320222/2811843 (the whole point being to structure schema in a way, that if-then-else fails on a single keyword schema and rest of schema logic sits under other keywords)另请参见此处的替代模式 2: https : //stackoverflow.com/a/53320222/2811843 (重点是以某种方式构建模式,即 if-then-else 在单个关键字模式上失败,并且其余的模式逻辑位于其他关键字下)

Having said that, you may always check that approach with your tooling and if necessary file a report to your favourite lib authors about error messaging details for failed if-then-else schemas.话虽如此,您可以始终使用您的工具检查该方法,并在必要时向您最喜欢的库作者提交一份报告,了解失败的 if-then-else 模式的错误消息详细信息。

alternative with "dependencies"带有“依赖关系”的替代方案

Another alternative for your case is using "dependencies" keyword from draft-06, invert the initial logic and shape "definitions" nodes so it leads directly to unique error:您的情况的另一种选择是使用draft-06中的“dependencies”关键字,反转初始逻辑和形状“定义”节点,以便直接导致唯一错误:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "ips": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
                "type": "string",
                "pattern": "[^ ]",
                "minLength": 1,
                "maxLength": 50
            }
        },
        "app_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "enum": [
                "test",
                "rest"
            ]
        }
    },
    "required": [
        "app_name"
    ],
    "dependencies" : {
     "ips" : {
        "properties": {
        "app_name": {"$ref":"#/definitions/allowed-app_name-value/rest"}
      },
     },
     "name" : {
      "properties": {
        "app_name": {"$ref":"#/definitions/allowed-app_name-value/test"}
      }, 
     }   
    },
    "definitions" : {
      "allowed-app_name-value" : {
        "test" : {
          "enum": ["test"]
        },
        "rest" : {
          "enum": ["rest"]
        }
      }
    },
    "examples" : [
      {
        "app_name" : "rest",
      },
      {
        "app_name" : "test",
      },
      {
        "app_name" : "test",
        "ips" : [
         "something1",
         "something2"
        ]
      },
      {
        "app_name" : "rest",
        "name" : "qwerty"
      },
      {
        "app_name" : "test",
        "name" : "qwerty"
      },
      {
        "app_name" : "rest",
        "ips" : [
          "something1",
          "something2"
        ]
      }
    ]
}

yet it's still a naming workaround aimed to identify exact error in a human readable way.但它仍然是一种命名解决方法,旨在以人类可读的方式识别确切的错误。 For instance, the jsonschema .net will feed you with JSON line numbers and messages like documented in here: https://www.newtonsoft.com/jsonschema/help/html/JTokenIsValidWithValidationErrors.htm例如,jsonschema .net 将为您提供 JSON 行号和消息,如此处记录的: https ://www.newtonsoft.com/jsonschema/help/html/JTokenIsValidWithValidationErrors.htm

Each tool has it's own error messaging approach.每个工具都有自己的错误消息传递方法。 Please check JSON Schema team on github, as there's some work on unifying output for JSON Schema validation in progress for next draft.请在 github 上查看 JSON Schema 团队,因为有一些关于统一输出以用于下一个草案的 JSON Schema 验证的工作。

Whenever analysing errors programatically, you may want to pay attention to error indexes (schemas are usually nested in schemas) if they appear, on which line the error occured etc..每当以编程方式分析错误时,您可能需要注意错误索引(模式通常嵌套在模式中)是否出现,错误发生在哪一行等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM