Реструктуризация файла JSON в JAVA - PullRequest
0 голосов
/ 17 октября 2018

У меня есть следующий пример из файла 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 голосов
/ 18 октября 2018
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()));
    }
}
0 голосов
/ 18 октября 2018

Я написал код, чтобы сделать то, что вам нужно, но сначала вы должны добавить эту библиотеку в свой проект, если у вас нет библиотеки org.json.zip , потому что у меня не былобиблиотека для разбора 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 data: -

...
//get the json array
jsonArray = readFromFile("FilePath");
...
0 голосов
/ 18 октября 2018

Вы можете создать карту карт для представления вашей группировки по «Файл» и «Класс» для вашего списка (внутренних) объектов 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)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...