比较两个具有相同嵌套结构和相同键但值可以不同的json?

问题描述

例如:

Json A =>
{
  "customer": {
    "age": 29,"fullName": "Emily Jenkins","year":1988,"address":{
        "lineOne":"lineOne","lineTwo":"lineTwo"
    }
},"handset":{
    "phone":"0123456789","colour":"black"
  }
}

Json B =>
    {
      "customer": {
        "fullName": "Sammy J","age": 31,"year":1985,"address":{
            "lineTwo":"lineTwo","lineOne":"lineOne"
        }
    },"handset":{
        "colour":"red","phone":"0123456788"
      }
    }

我想比较这两个json,并且当键匹配并且两个json结构相同时,它应该返回true。那么有没有一种干净的方法呢?

我知道使用Gson lib可以比较两个JsonElement,但是它们也将匹配值,但我不想将其作为用例的约束。

JsonParser parser = new JsonParser();
JsonElement p1 = parser.parse(JsonA);
JsonElement p2 = parser.parse(JsonB);
System.out.printf(p1.equals(p2) ? "Equal" : "Not Equal"); //it returns true if values are same.

解决方法

这确实是JSON模式验证的一种情况,请参考CoreValidation

有一些可用的JSON模式验证器,对于以下示例,我正在使用enter link description here。库二进制文件在Maven中可用,也可以下载(连同所有依赖项和javadoc)from here。其他验证器也可用from here

经历this guide也许会有所帮助。

该示例的架构如下(SampleJsonSchema.json):

{
    "$schema":"http://json-schema.org/draft-07/schema#","id":"http://test.org/sampleJsonSchema1","title":"SampleJSONSchema","description":"This is the description","type":"object","properties":{
    
        "customer":{
        
            "type":"object","properties":{
            
                "fullname":{"type":"string"},"age":{"type":"integer"},"year":{"type":"integer"},"address":{
            
                    "type":"object","properties":{
                    
                        "lineOne":{"type":"string"},"lineTwo":{"type":"string"}
                    
                    },"required":["lineOne","lineTwo"],"maxProperties":2

                }
            
            },"required":["fullname","age","year","address"],"maxProperties":4   
        
        },"handset":{
        
            "type":"object","properties":{
            
                "phone":{"type":"string"},"colour":{"type":"string"}
            
            },"required":["phone","colour"],"maxProperties":2
        
        }
    
    }
}

使用的数据如下(SampleJsonData.json:

{
  "customer": {
  
   "fullname": "Emily Jenkins","age": 29,"year":1988,"address":{
    
        "lineOne":"lineOne","lineTwo":"lineTwo"
    }
},"handset":{
    "phone":"0123456789","colour":"black"
  }
}

验证例程如下:

打包org.test;

import java.io.File;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;

public class JsonValidation {

    public static void main(String[] args) throws Exception{
        
        
        String jsonSchemaPath="F:\\workspaces\\utilities\\TestJava\\jsonSchema\\SampleJsonSchema.json";
        String jsonDataPath="F:\\workspaces\\utilities\\TestJava\\jsonSchema\\SampleJsonData.json";
        
        ObjectMapper mapper=new ObjectMapper();
        
        JsonNode schemaNode=mapper.readValue(new File(jsonSchemaPath),JsonNode.class);
        JsonNode dataNode=mapper.readValue(new File(jsonDataPath),JsonNode.class);
        
        JsonSchema jsonSchema=JsonSchemaFactory.byDefault().getJsonSchema(schemaNode);
        
        ProcessingReport validationReport=jsonSchema.validate(dataNode);
        
        System.out.println(validationReport.toString());

    }//main closing

}//class closing

通过更改架构和数据以观察不同的结果,可以运行许多测试。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...