簡體   English   中英

jsonschema 驗證未按預期返回錯誤?

[英]jsonschema validation not returning error as expected?

我正在使用這個模式,我希望有基於值的條件模式。

如果app_name是“test”,那么屬性名稱應該是必需的。

如果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"
    ]
}

我正在使用以下代碼

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

我收到以下驗證錯誤

'rest' 不是 ['test'] 之一

驗證架構中的“枚舉”失敗[0]['properties']['app_name']: {'enum': ['test']}

在實例['app_name']:'休息'

我不確定架構本身是否無效或者庫是否存在問題,如果 self.

我在用

蟒蛇 2.7

jsonschema 2.6.0

好的,模式中似乎有錯字。 “T芸香”,而不是“T芸香”。

你有:

"uniqueItems": True,

而據我所知,它應該是(盡管它仍然可能取決於模式驗證器的實現)

"uniqueItems": true,

(參見: http : //www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf第 5 節 JSON 值和一般https://www.json.org/ - JSON 模式是一個JSON 文檔,符合 JSON 標准)

我已經通過https://www.jsonschemavalidator.net/ 上的.net 在線 JSON 模式驗證器運行它,它立即指出了上述模式可能存在的錯誤。

根據您在 2018 年 11 月 16 日的評論,更正錯字后似乎可以完美運行:

當我在 app_name 中傳遞一個值“rest”時。 我期待錯誤消息“ips”字段是必需的。 – 薩欽·阿里亞爾

完整模式(請注意“示例”部分 - 只有最后 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"
        ]
      }
    ]
}

您能否更正模式中的項目並嘗試使用您的工具並讓我們知道結果?

最重要的是:

如果您通過驗證 JSON 對象,如:

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

針對您的架構,其中使用了“oneOf” - 驗證器將/應該針對“oneOf”數組中的所有架構運行對象,以確保它與提供的架構之一完全匹配。 因此,“oneOf/0/”模式的錯誤是有效的 - “app_name”:“rest”不會針對定義的枚舉進行驗證。 驗證器不知道您通過提供特定的 JSON 以針對模式進行驗證是什么意思,因此如果不滿足“allOf”(邏輯 XOR)條件,我希望在“oneOf”數組中運行 JSON 的所有模式都會出現錯誤(即使這些對您來說似乎是誤報)。

如果缺少某些錯誤消息,您可能需要考慮檢查/向庫作者報告您的確切情況。

希望它有所幫助。

更新

因此,您似乎是另一個追逐有意義錯誤的人;-) 是的,使用邏輯運算符時可能會很痛苦。

對於像上面這樣的簡單情況,您可以使用draft-07 if-then-else方法,但是有一個警告 - 請參閱備注。

首先是模式(注意我是如何用兩個“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"
        ]
      }
    ]
}

評論

模式驗證器 jsonschema.net 在簡單情況下傾向於提供精確的 if-then-else 錯誤,當“then”和“else”中的模式不包含嵌套的“if-then”並且由單個語句/模式表達式組成時。 但是,每當構建更復雜的案例時,您可能會遇到一般錯誤消息,例如: JSON 與“then”中的架構不匹配。 JSON 與“else”中的架構不匹配。 沒有額外的細節(你需要自己檢查 python 輸出)。 您可以通過適當地塑造依賴項或子模式來解決這個問題,但是對於非常復雜的模式,如果您在查看詳細的錯誤消息,無論如何您都可能面臨驗證器實現錯誤消息的限制。 另請參見此處的替代模式 2: https : //stackoverflow.com/a/53320222/2811843 (重點是以某種方式構建模式,即 if-then-else 在單個關鍵字模式上失敗,並且其余的模式邏輯位於其他關鍵字下)

話雖如此,您可以始終使用您的工具檢查該方法,並在必要時向您最喜歡的庫作者提交一份報告,了解失敗的 if-then-else 模式的錯誤消息詳細信息。

帶有“依賴關系”的替代方案

您的情況的另一種選擇是使用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"
        ]
      }
    ]
}

但它仍然是一種命名解決方法,旨在以人類可讀的方式識別確切的錯誤。 例如,jsonschema .net 將為您提供 JSON 行號和消息,如此處記錄的: https ://www.newtonsoft.com/jsonschema/help/html/JTokenIsValidWithValidationErrors.htm

每個工具都有自己的錯誤消息傳遞方法。 請在 github 上查看 JSON Schema 團隊,因為有一些關於統一輸出以用於下一個草案的 JSON Schema 驗證的工作。

每當以編程方式分析錯誤時,您可能需要注意錯誤索引(模式通常嵌套在模式中)是否出現,錯誤發生在哪一行等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM