Câu hỏi Hợp nhất (Concat) Nhiều JSONObject


Tôi đang tiêu thụ một số JSON từ hai nguồn khác nhau, tôi kết thúc bằng hai JSONObjectvà tôi muốn kết hợp chúng thành một.

Dữ liệu:

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

"Object2": {
    "Stringkey":"StringVal",
    "Stringkey":"StringVal",
    "Stringkey":"StringVal",
}

Mã, sử dụng http://json.org/java/ thư viện:

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

Vì vậy, trong tình huống này tôi muốn kết hợp Obj1 và Obj2, hoặc tạo ra một hoàn toàn mới JSONObject hoặc concat một đến khác. Bất kỳ ý tưởng nào ngoài việc kéo chúng ra xa nhau và cá nhân thêm vào bởi putS?


41
2018-03-08 17:12


gốc




Các câu trả lời:


Nếu bạn muốn một đối tượng mới có hai khóa, Object1 và Object2, bạn có thể thực hiện:

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

Nếu bạn muốn hợp nhất chúng, ví dụ: một đối tượng cấp cao nhất có 5 khóa (Stringkey1, ArrayKey, StringKey2, StringKey3, StringKey4), tôi nghĩ bạn phải làm điều đó theo cách thủ công:

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

Điều này sẽ dễ dàng hơn nhiều nếu JSONObject triển khai Bản đồvà hỗ trợ putAll.


41
2018-03-08 17:58



Tôi đang cố gắng sử dụng đoạn mã thứ hai của bạn trong Android, nhưng tôi không thấy hàm getNames tĩnh trên JSONObject. Điều này đã được thêm vào trong phiên bản mới hơn của thư viện org.json chưa? - Austyn Mahoney
@AustynMahoney, không chắc chắn về lịch sử, nhưng đối với Android bạn có thể sử dụng phương pháp cá thể JSONObject.names. - Matthew Flaschen
@AustynMahoney Nó không có trong thư viện json android tôi đã thử nó rồi. Nó cũng không được đề cập trong tài liệu android. Nó chỉ được đề cập ở đây json.org/javadoc/org/json/JSONObject.html - kishore
Phương thức JSONObject.getNames () sẽ trả về null nếu jsonobject rỗng. Bạn cũng cần kiểm tra tình trạng này. - Ehsan


Bạn có thể tạo một JSONObject mới như sau:

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));
    }
}

Với mã này, nếu bạn có bất kỳ phím lặp lại nào giữa Obj1 và Obj2 giá trị trong Obj2 sẽ vẫn còn. Nếu bạn muốn các giá trị trong Obj1 để được giữ, bạn nên đảo ngược thứ tự của mảng trong dòng 2.


19
2018-03-08 17:55



Tôi không biết về phương thức tĩnh JSONObject.getNames, nó làm cho mã đơn giản hơn rất nhiều, xem câu trả lời của Matthew bên dưới để làm giảm mã bằng cách sử dụng nó. - Santi P.
Trong dòng đầu tiên thêm new trước JSONObject(), chỉnh sửa không được phép cho dưới 6 ký tự. - Anas Azeem


Trong một số trường hợp, bạn cần hợp nhất sâu, tức là hợp nhất nội dung của các trường có tên giống hệt nhau (giống như khi sao chép các thư mục trong Windows). Chức năng này có thể hữu ích:

/**
 * 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"}}
}

16
2018-02-25 15:31



Điều gì xảy ra nếu một giá trị trong 'nguồn' thuộc kiểu JSONArray ?. Trong trường hợp này, chúng ta cần hợp nhất mảng này với JSONArray tương đương của đối tượng đích. - pgoldweic


Phương thức trình bao này sẽ giúp:

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;
}

3
2018-04-01 07:38





Một phương thức sẵn sàng để hợp nhất bất kỳ số lượng JSONObject nào:

/**
 * 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;
}

2
2018-05-23 06:08





Ngoài câu trả lời của @ erel, tôi phải thực hiện chỉnh sửa này (tôi đang sử dụng org.json.simple) đến bên ngoài else để xử lý 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);
            }

0
2017-07-25 10:32





Nhờ Erel. Đây là phiên bản 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}

}

0
2017-08-04 02:39





Tôi đã sử dụng chuỗi để nối đối tượng mới với một đối tượng hiện có.


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();
}

0
2017-08-31 02:53





Đối với tôi, hàm đó hoạt động:

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;
}

(thông báo) - điều này thực hiện các concataion của json là cho nhập khẩu org.json.simple.JSONObject;


0
2017-08-05 01:20