Json Schema 未在 2020-12 草案版本中正确评估 if else 条件

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

我使用一个 json 模式,它引用另一个 json 模式,如下所示: 架构 1 (cache_test.json)

{
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "https://json-schema.org/schema/cache_test.json",
        "type": "object",
        "properties": {
            "accName": {
                "type": "string"
            },
            "insData": {
                "$ref": "./test.json"
            },
            "secData": {
                "$ref": "./test.json"
            }
        },
        "required": [
            "accName",
            "insData"
        ],
        "definitions": {
            "string_validation": {
                "type": "string"
            },
            "string_or_null_validation": {
                "type": ["string", "null"]
            }
        }
    }

从模式 1 引用的模式 2(test.json) 定义如下:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://json-schema.org/schema/test.json",
    "type": "array",
    "items":
    {
        "type": "object",
        "properties": {
            "referenceval": {
                "$ref": "#/definitions/string_validation"
            },
            "tableName": {
                "enum": [
                    "TABLE1",
                    "TABLE2",
                    "TABLE3",
                    "TABLE4",
                    "TABLE5",
                    "TABLE6",
                    "TABLE7",
                    "TABLE8",
                    "TABLE9"
                ]
            },
            "code": {
                "$ref": "#/definitions/string_validation"
            },
            "contractType": {
                "$ref": "#/definitions/string_validation"
            }
        },
        "allOf": [
            {
                "if": {
                    "properties": {
                        "tableName": {
                            "const": "TABLE1"
                        }
                    }
                },
                "then": {
                    "required": [
                        "referenceval"
                    ]
                }
            },
            {
                "if": {
                    "properties": {
                        "tableName": {
                            "const": "TABLE2"
                        }
                    }
                },
                "then": {
                    "required": [
                        "code"
                    ]
                }
            },
            {
                "if": {
                    "properties": {
                        "tableName": {
                            "const": "TABLE3"
                        }
                    }
                },
                "then": {
                    "required": [
                        "contractType"
                    ]
                }
            }
        ]
    },
    "definitions": {
        "string_validation": {
            "type": "string"
        },
        "string_or_null_validation": {
            "type": ["string", "null"]
        }
    }
}

问题是在 Schema 2 (test.json) 中,它没有正确验证 if-else 条件。即,例如,如果我的 json 输入中的 tableName 是“TABLE2”,并且输入中不存在字段“referenceval”,则它会抱怨需要“referenceval”。根据 if 条件,仅当 tableName 为“TABLE1”时才需要“referenceval”。我正在使用库“com.networknt json-schema-validator”,我用来验证上述 json 的代码如下:

public List<String> validateInputDataTest(String jsonInput){
    List<String> validationErrors = new ArrayList<>();
    try{
      InputStream mainSchemaStream = MyClass.class.getClassLoader().getResourceAsStream("schema/cache_test.json");
      InputStream subSchemaStream = MyClass.class.getClassLoader().getResourceAsStream("schema/test.json");
      ObjectMapper mapperSubSchema = new ObjectMapper();
      JsonNode jsonNodeSubSchema = mapperSubSchema.readValue(subSchemaStream, JsonNode.class);
      String referencedSchema = mapperSubSchema.writeValueAsString(jsonNodeSubSchema);

      JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012,
          builder -> builder.schemaLoaders(schemaLoaders -> schemaLoaders.schemas(
              Collections.singletonMap("https://json-schema.org/schema/test.json", referencedSchema))));

      JsonSchema schema = factory.getSchema(mainSchemaStream);

      SchemaValidatorsConfig schemaValidatorsConfig = new SchemaValidatorsConfig();
      schemaValidatorsConfig.setFailFast(false);
      schemaValidatorsConfig.setHandleNullableField(true);

      ObjectMapper mapper = new ObjectMapper();
      JsonNode jsonNode = mapper.readTree(jsonInput);
      Set<ValidationMessage> validationMessages = schema.validate(jsonNode);
      for(ValidationMessage validationMessage : validationMessages){
        validationErrors.add(validationMessage.getMessage());
        System.out.println("Validation error:" +  validationMessage.getMessage());
      }
    }catch(Exception e){
      log.error("Error while validating input json");
      validationErrors.add("Error while validating input json");
    }
    return validationErrors;
  }

请让我知道如何才能正确验证上述架构中的 if else 条件?

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

您已表示您正在使用

com.networknt.json-schema-validator
,但使用 https://www.itb.ec.europa.eu/json/any/upload 进行测试,将其用作上游组件不会显示任何错误
如果仅使用 
[{"tableName": "TABLE2", "code": ""}]
 模式,则将 test.json
作为输入。

我怀疑发生的情况是输入数据遗漏或拼错了

tableName
属性导致错误。

如果您将

if
properties
一起使用,您通常也会使用
required
,否则如果省略该属性,它将成功验证,因为属性是可选的。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.