如果存在if-else,则JSON架构验证器会显示其他错误消息

问题描述 投票:0回答:1

这里是我的JSON模式(假设的,因为我不能分享我的实际模式)和JSON。 if-then-else条件类似于:

一次只能显示三(3)个国家中的一(1)个用于定义统计信息。

架构

    {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "type": "object",
        "required": [
            "year",
            "country",
            "statistics"
        ],
        "definitions": {
        "statisticsUsa": {
          "if": {
            "properties": {
              "type": {
                "const": "statisticsUsa"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "statisticsUsa"
              }
            }
          }
        },
            "statisticsFinland": {
          "if": {
            "properties": {
              "type": {
                "const": "statisticsFinland"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "statisticsFinland"
              }
            }
          }
        },
        "statisticsGermany": {
          "if": {
            "properties": {
              "type": {
                "const": "statisticsGermany"
              }
            },
            "required": [
              "type", "literacy"
            ]
          },
          "then": {
            "properties": {
              "type": {
                "const": "statisticsGermany"
              },
              "literacy": {
                "type": "string"
              }
            }
          }
        }
        },
        "properties": {
            "year": {
                "type": "string"
            },
            "country": {
                "type": "string",
                "enum": [
                    "USA",
                    "FINLAND",
                    "GERMANY"
                ]
            },
            "statistics": {

                "type": "array",
                "allOf": [{
                        "if": {
                            "contains": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "statisticsUsa"
                                        ]
                                    }
                                }
                            }
                        },
                        "then": {
                            "not": {
                                "contains": {
                                    "type": "object",
                                    "properties": {
                                        "type": {
                                            "type": "string",
                                            "enum": [
                                                "statisticsFinland",
                                                "statisticsGermany"
                                            ]
                                        }
                                    }
                                }
                            }
                        },"errorMessage" :"Only USA applicable at a time for statistics"
                    },
                    {
                        "if": {
                            "contains": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "statisticsFinland"
                                        ]
                                    }
                                }
                            }
                        },
                        "then": {
                            "not": {
                                "contains": {
                                    "type": "object",
                                    "properties": {
                                        "type": {
                                            "type": "string",
                                            "enum": [
                                                "statisticsUsa",
                                                "statisticsGermany"
                                            ]
                                        }
                                    }
                                }
                            }
                        },"errorMessage" :"Only Finland applicable at a time for statistics"
                    },
                    {
                        "if": {
                            "contains": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "statisticsGermany"
                                        ]
                                    }
                                }
                            }
                        },
                        "then": {
                            "not": {
                                "contains": {
                                    "type": "object",
                                    "properties": {
                                        "type": {
                                            "type": "string",
                                            "enum": [
                                                "statisticsUsa",
                                                "statisticsFinland"
                                            ]
                                        }
                                    }
                                }
                            }
                        },"errorMessage" :"Only Germany applicable at a time for statistics"
                    }

                ],
                "minItems": 1,
                "items": {
                    "anyOf": [{
                            "$ref": "#/definitions/statisticsUsa"
                        },
                        {
                            "$ref": "#/definitions/statisticsFinland"
                        },
                        {
                            "$ref": "#/definitions/statisticsGermany"
                        }
                    ]
                }
            }
        }
    }

杰森1

    const Ajv = require('ajv');
    const ajv = new Ajv({
        allErrors: true,
        jsonPointers: true
    });

    const schema1 = require("./sof.json");
    require('ajv-errors')(ajv /*, {singleError: true} */);
    const data = {
      year: "2000",
      country: "USA",
      statistics: [
        {"type":"statisticsUsa"},
        {"type":"statisticsFinland"}
      ]
    }

    let valid = ajv.validate(schema1, data); //schema, data
    if (!valid) {
      console.log(`${JSON.stringify(ajv.errors,null,2)}`);
    }

在这里,当我有2个国家/地区时,我可以看到2个错误作为数组的一部分。我的问题是,“芬兰”不能与“美国”一起使用,“仅一次适用于美国的统计数据”的错误就不能被接受,因为它满足条件。但是,对于Findland的错误是可以接受的。

    [
      {
        "keyword": "errorMessage",
        "dataPath": "/statistics",
        "schemaPath": "#/properties/statistics/allOf/0/errorMessage",
        "params": {
          "errors": [
            {
              "keyword": "not",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/0/then/not",
              "params": {},
              "message": "should NOT be valid"
            },
            {
              "keyword": "if",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/0/if",
              "params": {
                "failingKeyword": "then"
              },
              "message": "should match \"then\" schema"
            }
          ]
        },
        "message": "Only USA applicable at a time for statistics"
      },
      {
        "keyword": "errorMessage",
        "dataPath": "/statistics",
        "schemaPath": "#/properties/statistics/allOf/1/errorMessage",
        "params": {
          "errors": [
            {
              "keyword": "not",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/1/then/not",
              "params": {},
              "message": "should NOT be valid"
            },
            {
              "keyword": "if",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/1/if",
              "params": {
                "failingKeyword": "then"
              },
              "message": "should match \"then\" schema"
            }
          ]
        },
        "message": "Only Finland applicable at a time for statistics"
      }
    ]

此外,如果我在JSON中将'德国'添加为,

{
  year: "2000",
  country: "USA",
  statistics: [
    {"type":"statisticsUsa"},
    {"type":"statisticsFinland"},
    {"type":"statisticsGermany"}
  ]
}

它作为数组的一部分抛出3个错误(请参见下文)。为什么?

  1. [从技术上讲,模式验证器应该在第二项处停止,并且应该忽略错误数组中的“德国”,因为它发现'Findland'条目违反了if-else条件。
  2. [此外,schema-validator是否从'statistics'数组(从JSON)中获取每个项目,并为每次运行检查'allOf'中的条件,所以这就是数组中3个错误条目的原因。我的理解正确吗? (如果您看到上面的第一个错误数组,那么它只有2个条目)

    [
      {
        "keyword": "errorMessage",
        "dataPath": "/statistics",
        "schemaPath": "#/properties/statistics/allOf/0/errorMessage",
        "params": {
          "errors": [
            {
              "keyword": "not",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/0/then/not",
              "params": {},
              "message": "should NOT be valid"
            },
            {
              "keyword": "if",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/0/if",
              "params": {
                "failingKeyword": "then"
              },
              "message": "should match \"then\" schema"
            }
          ]
        },
        "message": "Only USA applicable at a time for statistics"
      },
      {
        "keyword": "errorMessage",
        "dataPath": "/statistics",
        "schemaPath": "#/properties/statistics/allOf/1/errorMessage",
        "params": {
          "errors": [
            {
              "keyword": "not",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/1/then/not",
              "params": {},
              "message": "should NOT be valid"
            },
            {
              "keyword": "if",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/1/if",
              "params": {
                "failingKeyword": "then"
              },
              "message": "should match \"then\" schema"
            }
          ]
        },
        "message": "Only Finland applicable at a time for statistics"
      },
      {
        "keyword": "errorMessage",
        "dataPath": "/statistics",
        "schemaPath": "#/properties/statistics/allOf/2/errorMessage",
        "params": {
          "errors": [
            {
              "keyword": "not",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/2/then/not",
              "params": {},
              "message": "should NOT be valid"
            },
            {
              "keyword": "if",
              "dataPath": "/statistics",
              "schemaPath": "#/properties/statistics/allOf/2/if",
              "params": {
                "failingKeyword": "then"
              },
              "message": "should match \"then\" schema"
            }
          ]
        },
        "message": "Only Germany applicable at a time for statistics"
      }
    ]

jsonschema json-schema-validator ajv
1个回答
0
投票

您已经自己推论了:allOf contains应用所有子方案并检查所有数组项。

如果只需要一条错误消息,则应该确定国家/地区的优先级,并且仅为其余国家/地区而不是所有国家/地区签入随后的allOf部分。例如:

  1. 如果数组包含“ USA”条目,则“ GERMANY”和“ FINLAND”都不应该出现(因为您已经拥有它)
  2. 如果数组包含“ GERMANY”条目,则不应存在“ FINLAND”条目(再次not再次检查“ USA”)
  3. 如果阵列包含“ FINLAND”条目,则上面的两个检查已经涵盖了可能的情况–此处无需任何其他检查。

这样,您永远不会同时遇到多个这些错误。

© www.soinside.com 2019 - 2024. All rights reserved.