在JAVA中重组JSON文件

时间:2018-10-17 19:04:26

标签: java json file

我从JSON文件中获取以下示例:

[
{
  "0":
  {
    "File":"file1.java",
    "Class":"com.ETransitionActionType",
    "Method":"values",
    "Annotation":"Not Found"
  }
},
{
  "1":
  {
    "File":"file2.java",
    "Class":"com.ETransitionParams",
    "Method":"values",
    "Annotation":"Not Found"
  }
},
{
  "2":
  {
    "File":"file3.java",
    "Class":"com.phloc.commons.id.IHasID",
    "Method":"getID",
    "Annotation":"Not Found"
  }
},
{
  "4":
  {
    "File":"file3.java",
    "Class":"com.ExecuteTransitionActionHandler",
    "Method":"createBadRequestResponse",
    "Annotation":"Not Found"
  }
},
{
  "5":
  {
    "File":"file3.java",
    "Class":"com.ExecuteTransitionActionHandler",
    "Method":"extractParametersFromAction",
    "Annotation":"Not Found"
  }
}]

如何使用Java重新构建此文件,使其看起来像这样:

[{
    "file1.java": {
        "com.ETransitionActionType": {
            "values": {
                "Annotation": "Not Found"
            }
        }
    }
},
{
    "file2.java": {
        "com.ETransitionParams": {
            "values": {
                "Annotation": "Not Found"
            }
        }
    }
},
{
    "file3.java": {
        "com.phloc.commons.id.IHasID": {
            "getID": {
                "Annotation": "Not Found"
            }
        },
        "com.ExecuteTransitionActionHandler": {
            "getID": {
                "Annotation": "Not Found"
            },
            "extractParametersFromAction": {
                "Annotation": "Not Found"
            }
        }
    }
}
]

即遍历JSON文件,进行搜索,并且无论“文件”属性具有相同的值(例如“ file3.java”),我们都在其中列出所有相关的类和方法,并且对“类”属性同样适用,如果它具有相同的名称,我们将列出其中的所有方法(因此就像对“文件”和“类”属性的值进行比较和排序一样)。 我从JSON简单库开始,像下面的代码那样编写,但是不知道进一步的方法!

Object object = (JSONArray)parser.parse(new FileReader("rawOutput.json"));            
JSONArray jsonArray =  (JSONArray) object;
for(int i = 0; i < jsonArray.size(); i++) {
    System.out.println(jsonArray.get(i));
    JSONObject jsonObject = (JSONObject)jsonArray.get(i);
    String c = jsonObject.get("" + i + "").toString();
}

有什么想法吗?非常感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Foo {
    public static void main(String... args) throws IOException {
        String json = formatJson(new FileReader("rawOutput.json"));
        System.out.println(json);
    }

    public static String formatJson(Reader reader) throws IOException {
        // group array items by fileName
        final Function<List<Map<String, Object>>, Map<String, List<Object>>> groupByFileName =
                data -> data.stream().collect(Collectors.groupingBy(map -> (String)map.get("File"), TreeMap::new,
                        Collectors.mapping(Function.identity(), Collectors.toList())));

        // convert source item structure into required
        final Function<Map.Entry<String, List<Object>>, Map<String, Object>> convert = entry -> {
            Map<String, Map<String, Map<String, String>>> tmp = new LinkedHashMap<>();

            entry.getValue().stream()
                    .map(value -> (Map<String, String>)value)
                    .forEach(map -> {
                        Map<String, Map<String, String>> classes = tmp.computeIfAbsent(map.get("Class"), cls -> new TreeMap<>());
                        Map<String, String> methods = classes.computeIfAbsent(map.get("Method"), method -> new TreeMap<>());

                        map.entrySet().stream()
                                .filter(e -> !"Class".equals(e.getKey()) && !"Method".equals(e.getKey()) && !"File".equals(e.getKey()))
                                .forEach(e -> methods.put(e.getKey(), e.getValue()));
                    });

            return Collections.singletonMap(entry.getKey(), tmp);
        };

        ObjectMapper mapper = new ObjectMapper();

        // read json as array of Maps
        List<Map<String, Object>> data = Arrays.stream(mapper.readValue(reader, Map[].class))
                .map(map -> map.values().iterator().next())
                .map(item -> (Map<String, Object>)item)
                .collect(Collectors.toList());

        return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(groupByFileName.apply(data).entrySet().stream()
                .map(convert).collect(Collectors.toList()));
    }
}

答案 1 :(得分:0)

我编写了代码来执行所需的操作,但是如果您还没有org.json.zip library,首先必须将此库添加到项目中,因为我没有用于解析{{1 }}文本,因此我使用该库来格式化Json数据,如果您不完全理解代码,对不起,因为您的请求并不像您自己所知道的那么容易,因此我创建了三个函数来获取结果,尽管我写了一些易于理解的注释,但这是代码:-

  

编辑

Json

使用我的代码得到的样本结果是:-

...
import org.json.*;
...
...
public static void main(String[] args) throws JSONException {
    System.out.println(getFormattedJson("json text"));
}

private static String getFormattedJson(String text) throws JSONException{
    JSONArray result = new JSONArray();
    JSONArray jsonArray = null;

    //get the json array
    jsonArray = new JSONArray(text);

    //loop through items in the array and insert them formatted to the result
    for (int i = 0; i < jsonArray.length(); i++) {
        //get object inside the number
        JSONObject object = getJsonChild(jsonArray.getJSONObject(i));

        //get these attributes
        String file = object.getString("File");
        String clas = object.getString("Class");
        String meth = object.getString("Method");
        String anno = object.getString("Annotation");

        //create a custom type of the object's attributes
        Map<String, String> map = new HashMap<>();
        map.put("Annotation", anno);
        Map<String, Object> map1 = new HashMap<>();
        map1.put(meth, map);
        Map<String, Object> map2 = new HashMap<>();
        map2.put(clas, map1);
        Map<String, Object> map3 = new HashMap<>();
        map3.put(file, map2);

        //loop through repeating values to also add them to one value as you expected
        for (int j = jsonArray.length() - 1; j > i; j--) {
            JSONObject obj = getJsonChild(jsonArray.getJSONObject(j));

            String file1 = obj.getString("File");
            String clas1 = obj.getString("Class");
            String meth1 = obj.getString("Method");
            String anno1 = obj.getString("Annotation");

            if (file1.equals(file)) {
                if (map2.containsKey(clas1)) {
                    if (childrenContains(map2, meth1)) {
                        //if the difference was annotation value
                        map.put("Annotation", anno1);
                    } else {
                        //if the difference was method names
                        Map<String, String> map_ = new HashMap<>();
                        map_.put("Annotation", anno1);
                        ((Map<String, Object>) map2.get(clas1)).put(meth1, map_);
                    }
                } else {
                    //if the difference was class names
                    Map<String, String> map_ = new HashMap<>();
                    map_.put("Annotation", anno1);
                    Map<String, Object> map1_ = new HashMap<>();
                    map1_.put(meth1, map_);
                    map2.put(clas1, map1_);
                }

                //remove the (value added) object
                jsonArray.remove(j);
            }
        }

        //add the map to the result
        result.put(map3);
    }

    return  result.toString(4);
}

private static boolean childrenContains(Map<String, Object> map1, String meth1) {
    for (String childKey : map1.keySet()) {
        Map<String, Object> child = (Map<String, Object>) map1.get(childKey);
        if (child.containsKey(meth1))
            return true;
    }
    return false;
}

private static JSONObject getJsonChild(JSONObject object) throws JSONException {
    Iterator<String> keys = object.keys();
    String key = "";
    while (keys.hasNext()) {
        key = (String) keys.next();
    }
    return object.getJSONObject(key);
}

如果您要从文件中获取[ {"file1.java": {"com.ETransitionActionType": {"values": {"Annotation": "Not Found"}}}}, {"file2.java": {"com.ETransitionParams": {"values": {"Annotation": "Not Found"}}}}, {"file3.java": { "com.ExecuteTransitionActionHandler": { "createBadRequestResponse": {"Annotation": "Not Found"}, "extractParametersFromAction": {"Annotation": "Not Found"} }, "com.phloc.commons.id.IHasID": {"getID": {"Annotation": "Not Found"}} }} ] 数据,请使用以下函数轻松创建json:-

JSONArray

并使用它来代替文本private static JSONArray readFromFile(String filePath){ try { BufferedReader br = new BufferedReader(new FileReader(filePath)); StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); } return new JSONArray(sb.toString()); } catch (Exception e) { System.out.println(e.getMessage()); return null; } } 数据:-

json

答案 2 :(得分:-1)

您可以创建一个地图映射,以表示(内部)JSON对象列表的“文件”和“类”分组。它可能看起来类似于

final Function<JSONObject, String> fileFunction = (JSONObject jsonObject) -> jsonObject.getString("File");
final Function<JSONObject, String> classFunction = (JSONObject jsonObject) -> jsonObject.getString("Class");
final Map<String, Map<String, List<JSONObject>>> groupedJsonObjects = jsonObjects.stream()
            .collect(Collectors.groupingBy(fileFunction, Collectors.groupingBy(classFunction)));