功能可以返回两个复杂的嵌套JSON和JSON数组的差异<

发布于 2025-02-12 03:28:49 字数 3462 浏览 0 评论 0原文

这里的目的是比较两个JSON文件并打印两个文件之间的差异。 它是带有嵌套JSON数组的嵌套JSON文件。这个想法是保持参考文件恒定并将新创建的文件与参考进行比较。

问题是因为JSON参数的顺序每次都在变化,并且以下代码比较行的行验证验证其变平的验证,并将其作为键值对和比较。它的失败是因为该顺序不维护。请注意,JSON文件具有300k行,并使用特定字段订购不起作用。

Gson gson = new Gson();
Type type = new TypeToken<Map<String, Object>>(){}.getType();

Map<String, Object> expMap = gson.fromJson(expectedJson, type);//expectedJson- json file parsed as a string
Map<String, Object> actMap = gson.fromJson(foundJson, type);
List<String> expMsgList=new ArrayList<>();
List<String> actMsgList=new ArrayList<>();
logger.info("Flatten the map inorder to compare the Nested JSON objects");
Map<String, Object> expFlatMap = FlatMapUtil.flatten(expMap);
Map<String, Object> actFlatMap = FlatMapUtil.flatten(actMap);
MapDifference<String, Object> difference = Maps.difference(expFlatMap, actFlatMap);


if(expMap.keySet().equals(actMap.keySet())) {
    if(!difference.entriesDiffering().isEmpty()) {
        difference.entriesDiffering().forEach((key, value) ->{
            String keyString=null;
            String keyStringarr[]=key.split("/");;
            
                keyString=keyStringarr[keyStringarr.length -1];
            
            
            if(!(fieldSkip.contains(keyString))){ //tp skip few parameters
                String valueExp=value.toString().split(",")[0].split("\\(")[1];
                String valueAct=value.toString().split(",")[1].split("\\)")[0];
                    
                
                String valueforKey="EXPECTED_VALUE="+valueExp+" and ACTUAL_VALUE="+ valueAct;
                failedItems.put(key, valueforKey); 
                logger.info(key + " -->"+valueforKey );
                }
            }
            );

实用文件以使JSON文件平坦

package com.cisco.cnp.commonUtils;

import java.util.AbstractMap.SimpleEntry;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public final class FlatMapUtil {

    private FlatMapUtil() {
        throw new AssertionError("No instances");
    }

    public static Map<String, Object> flatten(Map<String, Object> map) {
        return map.entrySet()
                .stream()
                .flatMap(FlatMapUtil::flatten)
                .collect(LinkedHashMap::new, (m, e) -> m.put("/" + e.getKey(), e.getValue()), LinkedHashMap::putAll);
    }

    private static Stream<Entry<String, Object>> flatten(Entry<String, Object> entry) {

        if (entry == null) {
            return Stream.empty();
        }

        if (entry.getValue() instanceof Map<?, ?>) {
            Map<?, ?> properties = (Map<?, ?>) entry.getValue();
            return properties.entrySet()
                    .stream()
                    .flatMap(e -> flatten(new SimpleEntry<>(entry.getKey() + "/" + e.getKey(), e.getValue())));
        }

        if (entry.getValue() instanceof List<?>) {
            List<?> list = (List<?>) entry.getValue();
            return IntStream.range(0, list.size())
                    .mapToObj(i -> new SimpleEntry<String, Object>(entry.getKey() + "/" + i, list.get(i)))
                    .flatMap(FlatMapUtil::flatten);
        }

        return Stream.of(entry);
    }
}
                    

The objective here is to compare two json files and print the difference between two of the files.
Its a nested JSON file with nested JSON array. The idea is to keep the reference file constant and compare the newly created file with reference.

Issue here is since the order of JSON parameter is varying every time and the below code is comparing line for line the validation Its flattening the JSON and making that as key value pair and comparing.Its failing because the order is not maintained. please note that the JSON file has 300k lines and ordering using a particular field doesn't work.

Gson gson = new Gson();
Type type = new TypeToken<Map<String, Object>>(){}.getType();

Map<String, Object> expMap = gson.fromJson(expectedJson, type);//expectedJson- json file parsed as a string
Map<String, Object> actMap = gson.fromJson(foundJson, type);
List<String> expMsgList=new ArrayList<>();
List<String> actMsgList=new ArrayList<>();
logger.info("Flatten the map inorder to compare the Nested JSON objects");
Map<String, Object> expFlatMap = FlatMapUtil.flatten(expMap);
Map<String, Object> actFlatMap = FlatMapUtil.flatten(actMap);
MapDifference<String, Object> difference = Maps.difference(expFlatMap, actFlatMap);


if(expMap.keySet().equals(actMap.keySet())) {
    if(!difference.entriesDiffering().isEmpty()) {
        difference.entriesDiffering().forEach((key, value) ->{
            String keyString=null;
            String keyStringarr[]=key.split("/");;
            
                keyString=keyStringarr[keyStringarr.length -1];
            
            
            if(!(fieldSkip.contains(keyString))){ //tp skip few parameters
                String valueExp=value.toString().split(",")[0].split("\\(")[1];
                String valueAct=value.toString().split(",")[1].split("\\)")[0];
                    
                
                String valueforKey="EXPECTED_VALUE="+valueExp+" and ACTUAL_VALUE="+ valueAct;
                failedItems.put(key, valueforKey); 
                logger.info(key + " -->"+valueforKey );
                }
            }
            );

Utility file for flattening the json file

package com.cisco.cnp.commonUtils;

import java.util.AbstractMap.SimpleEntry;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public final class FlatMapUtil {

    private FlatMapUtil() {
        throw new AssertionError("No instances");
    }

    public static Map<String, Object> flatten(Map<String, Object> map) {
        return map.entrySet()
                .stream()
                .flatMap(FlatMapUtil::flatten)
                .collect(LinkedHashMap::new, (m, e) -> m.put("/" + e.getKey(), e.getValue()), LinkedHashMap::putAll);
    }

    private static Stream<Entry<String, Object>> flatten(Entry<String, Object> entry) {

        if (entry == null) {
            return Stream.empty();
        }

        if (entry.getValue() instanceof Map<?, ?>) {
            Map<?, ?> properties = (Map<?, ?>) entry.getValue();
            return properties.entrySet()
                    .stream()
                    .flatMap(e -> flatten(new SimpleEntry<>(entry.getKey() + "/" + e.getKey(), e.getValue())));
        }

        if (entry.getValue() instanceof List<?>) {
            List<?> list = (List<?>) entry.getValue();
            return IntStream.range(0, list.size())
                    .mapToObj(i -> new SimpleEntry<String, Object>(entry.getKey() + "/" + i, list.get(i)))
                    .flatMap(FlatMapUtil::flatten);
        }

        return Stream.of(entry);
    }
}
                    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文