Объединение (Concat) Несколько JSONObjects

Я потребляю JSON из двух разных источников, у меня два JSONObject и я хотел бы объединить их в один.

Данные:

 "Object1": { "Stringkey":"StringVal", "ArrayKey": [Data0, Data1] } "Object2": { "Stringkey":"StringVal", "Stringkey":"StringVal", "Stringkey":"StringVal", } 

Код, используя http://json.org/java/ library:

 // jso1 and jso2 are some JSONObjects already instantiated JSONObject Obj1 = (JSONObject) jso.get("Object1"); JSONObject Obj2 = (JSONObject) jso.get("Object2"); 

Поэтому в этой ситуации я хотел бы объединить Obj1 и Obj2 , чтобы либо сделать совершенно новый JSONObject либо JSONObject один для другого. Любые идеи, помимо вытягивания их всех и индивидуального добавления,

Если вам нужен новый объект с двумя ключами Object1 и Object2, вы можете сделать:

 JSONObject Obj1 = (JSONObject) jso1.get("Object1"); JSONObject Obj2 = (JSONObject) jso2.get("Object2"); JSONObject combined = new JSONObject(); combined.put("Object1", Obj1); combined.put("Object2", Obj2); 

Если вы хотите объединить их, то, например, объект верхнего уровня имеет 5 ключей (Stringkey1, ArrayKey, StringKey2, StringKey3, StringKey4), я думаю, вам нужно сделать это вручную:

 JSONObject merged = new JSONObject(Obj1, JSONObject.getNames(Obj1)); for(String key : JSONObject.getNames(Obj2)) { merged.put(key, Obj2.get(key)); } 

Это было бы намного проще, если бы JSONObject реализовал Map и поддерживал putAll.

Вы можете создать новый JSONObject следующим образом:

 JSONObject merged = new JSONObject(); JSONObject[] objs = new JSONObject[] { Obj1, Obj2 }; for (JSONObject obj : objs) { Iterator it = obj.keys(); while (it.hasNext()) { String key = (String)it.next(); merged.put(key, obj.get(key)); } } 

С помощью этого кода, если у вас есть повторяющиеся ключи между Obj1 и Obj2 значение в Obj2 останется. Если вы хотите Obj1 значения в Obj1 , вы должны инвертировать порядок массива в строке 2.

В некоторых случаях требуется глубокое слияние, т. Е. Объединить содержимое полей с одинаковыми именами (точно так же, как при копировании папок в Windows). Эта функция может быть полезна:

 /** * Merge "source" into "target". If fields have equal name, merge them recursively. * @return the merged object (target). */ public static JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException { for (String key: JSONObject.getNames(source)) { Object value = source.get(key); if (!target.has(key)) { // new value for "key": target.put(key, value); } else { // existing value for "key" - recursively deep merge: if (value instanceof JSONObject) { JSONObject valueJson = (JSONObject)value; deepMerge(valueJson, target.getJSONObject(key)); } else { target.put(key, value); } } } return target; } /** * demo program */ public static void main(String[] args) throws JSONException { JSONObject a = new JSONObject("{offer: {issue1: value1}, accept: true}"); JSONObject b = new JSONObject("{offer: {issue2: value2}, reject: false}"); System.out.println(a+ " + " + b+" = "+JsonUtils.deepMerge(a,b)); // prints: // {"accept":true,"offer":{"issue1":"value1"}} + {"reject":false,"offer":{"issue2":"value2"}} = {"reject":false,"accept":true,"offer":{"issue1":"value1","issue2":"value2"}} } 

Этот метод обертки поможет:

 private static JSONObject merge(JSONObject... jsonObjects) throws JSONException { JSONObject jsonObject = new JSONObject(); for(JSONObject temp : jsonObjects){ Iterator keys = temp.keys(); while(keys.hasNext()){ String key = keys.next(); jsonObject.put(key, temp.get(key)); } } return jsonObject; } в private static JSONObject merge(JSONObject... jsonObjects) throws JSONException { JSONObject jsonObject = new JSONObject(); for(JSONObject temp : jsonObjects){ Iterator keys = temp.keys(); while(keys.hasNext()){ String key = keys.next(); jsonObject.put(key, temp.get(key)); } } return jsonObject; } 

Готовый способ объединить любое количество JSONObjects:

 /** * Merges given JSONObjects. Values for identical key names are merged * if they are objects, otherwise replaced by the latest occurence. * * @param jsons JSONObjects to merge. * * @return Merged JSONObject. */ public static JSONObject merge( JSONObject[] jsons) { JSONObject merged = new JSONObject(); Object parameter; for (JSONObject added : jsons) { for (String key : toStringArrayList(added.names())) { try { parameter = added.get(key); if (merged.has(key)) { // Duplicate key found: if (added.get(key) instanceof JSONObject) { // Object - allowed to merge: parameter = merge( new JSONObject[]{ (JSONObject) merged.get(key), (JSONObject) added.get(key)}); } } // Add or update value on duplicate key: merged.put( key, parameter); } catch (JSONException e) { e.printStackTrace(); } } } return merged; } /** * Convert JSONArray to ArrayList. * * @param jsonArray Source JSONArray. * * @return Target ArrayList. */ public static ArrayList toStringArrayList(JSONArray jsonArray) { ArrayList stringArray = new ArrayList(); int arrayIndex; for ( arrayIndex = 0; arrayIndex < jsonArray.length(); arrayIndex++) { try { stringArray.add( jsonArray.getString(arrayIndex)); } catch (JSONException e) { e.printStackTrace(); } } return stringArray; } 

В дополнение к ответу @ erel, мне пришлось сделать это редактирование (я использую org.json.simple ) для внешнего else для работы с JSONArray ‘s:

  // existing value for "key" - recursively deep merge: if (value instanceof JSONObject) { JSONObject valueJson = (JSONObject)value; deepMerge(valueJson, (JSONObject) target.get(key)); } // insert each JSONArray's JSONObject in place if (value instanceof JSONArray) { ((JSONArray) value).forEach( jsonobj -> ((JSONArray) target.get(key)).add(jsonobj)); } else { target.put(key, value); } 

Благодаря Эрелю. Вот версия Gson.

 /** * Merge "source" into "target". If fields have equal name, merge them recursively. * Null values in source will remove the field from the target. * Override target values with source values * Keys not supplied in source will remain unchanged in target * * @return the merged object (target). */ public static JsonObject deepMerge(JsonObject source, JsonObject target) throws Exception { for (Map.Entry sourceEntry : source.entrySet()) { String key = sourceEntry.getKey(); JsonElement value = sourceEntry.getValue(); if (!target.has(key)) { //target does not have the same key, so perhaps it should be added to target if (!value.isJsonNull()) //well, only add if the source value is not null target.add(key, value); } else { if (!value.isJsonNull()) { if (value.isJsonObject()) { //source value is json object, start deep merge deepMerge(value.getAsJsonObject(), target.get(key).getAsJsonObject()); } else { target.add(key,value); } } else { target.remove(key); } } } return target; } /** * simple test */ public static void main(String[] args) throws Exception { JsonParser parser = new JsonParser(); JsonObject a = null; JsonObject b = null; a = parser.parse("{offer: {issue1: null, issue2: null}, accept: true, reject: null}").getAsJsonObject(); b = parser.parse("{offer: {issue2: value2}, reject: false}").getAsJsonObject(); System.out.println(deepMerge(a,b)); // prints: // {"offer":{},"accept":true} a = parser.parse("{offer: {issue1: value1}, accept: true, reject: null}").getAsJsonObject(); b = parser.parse("{offer: {issue2: value2}, reject: false}").getAsJsonObject(); System.out.println(deepMerge(a,b)); // prints: // {"offer":{"issue2":"value2","issue1":"value1"},"accept":true} } 

Я использовал строку для конкатенации нового объекта на существующий объект.


 private static void concatJSON() throws IOException, InterruptedException { JSONParser parser = new JSONParser(); Object obj = parser.parse(new FileReader(new File(Main.class.getResource("/file/user.json").toURI()))); JSONObject jsonObj = (JSONObject) obj; //usernameJsonObj String [] values = {"0.9" , Date.from(Calendar.getInstance().toInstant()).toLocaleString()}, innermost = {"Accomplished", "LatestDate"}, inner = {"Lesson1", "Lesson2", "Lesson3", "Lesson4"}; String in = "Jayvee Villa"; JSONObject jo1 = new JSONObject(); for (int i = 0; i < innermost.length; i++) jo1.put(innermost[i], values[i]); JSONObject jo2 = new JSONObject(); for (int i = 0; i < inner.length; i++) jo2.put(inner[i], jo1); JSONObject jo3 = new JSONObject(); jo3.put(in, jo2); String merger = jsonObj.toString().substring(0, jsonObj.toString().length()-1) + "," +jo3.toString().substring(1); System.out.println(merger); FileWriter pr = new FileWriter(file); pr.write(merger); pr.flush(); pr.close(); } 

Для меня эта функция работала:

 private static JSONObject concatJSONS(JSONObject json, JSONObject obj) { JSONObject result = new JSONObject(); for(Object key: json.keySet()) { System.out.println("adding " + key + " to result json"); result.put(key, json.get(key)); } for(Object key: obj.keySet()) { System.out.println("adding " + key + " to result json"); result.put(key, obj.get(key)); } return result; } 

(уведомление) – эта реализация concataion json предназначена для импорта org.json.simple.JSONObject;

  • Что значит .d в JSON?
  • Как конвертировать JSON в XML или XML в JSON?
  • jackson не десериализует общий список, который он сериализовал
  • Как написать пользовательский десериализатор JSON для Gson?
  • Как разрешить выход ASMX-файла JSON
  • JSON и экранирующие символы
  • Преобразование объекта в строку JSON
  • Сохранять порядок ключей JSON во время преобразования JSON в CSV
  • : непризнанный селектор, отправленный в экземпляр
  • Ответ JQuery JSON всегда запускает ParseError
  • Как конвертировать RDF в довольно вложенный JSON с помощью java rdf4j
  • Давайте будем гением компьютера.