合并(Concat)多个JSONObjects
我正在消耗来自两个不同来源的一些JSON,我最终得到了两个JSONObject
,我想把它们合并成一个。
数据:
"Object1": { "Stringkey":"StringVal", "ArrayKey": [Data0, Data1] } "Object2": { "Stringkey":"StringVal", "Stringkey":"StringVal", "Stringkey":"StringVal", }
代码,使用http://json.org/java/库:
// jso1 and jso2 are some JSONObjects already instantiated JSONObject Obj1 = (JSONObject) jso.get("Object1"); JSONObject Obj2 = (JSONObject) jso.get("Object2");
所以在这种情况下,我想组合Obj1
和Obj2
,要么创build一个全新的JSONObject
,要么连接到另一个。 任何想法,除了把它们全部分开,单独joins?
如果你想要一个带有两个键的对象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,这将会容易得多。
你可以像这样创build一个新的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
之间有任何重复的键, Obj1
Obj2
的值将保留。 如果你想让Obj1
的值保持不变,你应该在第2行反转数组的顺序。
在某些情况下,您需要进行深度合并,即合并具有相同名称的字段内容(就像在Windows中复制文件夹时一样)。 这个function可能有帮助:
/** * 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<String> 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<String>. * * @param jsonArray Source JSONArray. * * @return Target ArrayList<String>. */ public static ArrayList<String> toStringArrayList(JSONArray jsonArray) { ArrayList<String> stringArray = new ArrayList<String>(); 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
的:
// 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); }
感谢Erel。 这是一个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<String,JsonElement> 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} }
我用string连接新对象到现有的对象。
私人静态无效concatJSON()抛出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(); }