首页 > 解决方案 > 迭代所有 json 对象并替换值

问题描述

我有以下 JSON:

{  
   "data":{  
      "attributes":{  
         "external-event-url":"http://example.com",
         "is-sponsors-enabled":"true",
         "is-ticketing-enabled":"true",
         "timezone":"UTC",
         "name":"${name_variable}",
         "ends-at":"2020-01-02T23:59:59.123456+00:00",
         "starts-at":"2020-01-01T23:59:59.123456+00:00"
      },
      "type":"event"
   }
}

我必须遍历 json 对象并替换以${eg开头的变量的值,${name_variable} 并且新的 json 应该采用相同的格式(提到替换变量的值${}

我如何迭代如此复杂的 Json 对象并替换变量中的值

我试过下面的代码,但没有按预期工作:

public Map<String, String> mapfillData(String jsonstr) {
    Map<String, String> map = new HashMap<String, String>();
    try {
        JSONObject jsonObject = new JSONObject(jsonstr);
        String[] keys = JSONObject.getNames(jsonObject);

        for (String key : keys) {
            try {
                if (jsonObject.get(key).toString().startsWith("${")) {
                    map.put(key, System.getProperty(jsonObject.get(key).toString()
                            .replace("${", "").replace("}", "")));
                } else {
                    if(isJSONValid(jsonObject.get(key).toString())){
                        mapfillData(jsonObject.get(key).toString());
                    }else{
                        map.put(key, jsonObject.get(key).toString());
                    }
                }

            } catch (Exception e) {

            }
        }
    } catch (JSONException e) {
        System.err.printf(jsonstr + " is not valid Json", e);
    }
    return map;
}

检查它是否是一个有效的 JSON 对象

public boolean isJSONValid(String test) {
    try {
        new JSONObject(test);
    } catch (JSONException ex) {
        // edited, to include @Arthur's comment
        // e.g. in case JSONArray is valid as well...
        try {
            new JSONArray(test);
        } catch (JSONException ex1) {
            return false;
        }
    }
    return true;
}

标签: javajsoniterator

解决方案


您的问题是,当您尝试递归处理 JSON 时,在每个递归级别,您正在处理不同的JSON 文档并将数据写入不同 Map的.

您的函数接受一个字符串,然后将其解析为JSONObject. 您创建一个Map来保存一些数据。第一次通过mapfillData,您只会找到一个密钥,data。然后,假设您的if逻辑工作正常(我没有尝试运行它),您将把 的内容呈现data到另一个字符串中并递归调用mapfillData.

现在您正在第二次调用mapfillData,并创建另一个Map. 这一次通过你找到attributesmapfillData第三次调用。在第三次调用中,您会找到一些变量并在将值写入Map. 在函数结束时,您返回Map,但调用者(对 的第二次调用mapfillData)对返回的 没有任何操作Map,并且您的所有数据都丢失了。

我会:

  • 解析一次 JSON,然后通过 JSONObject 结构递归。换句话说,递归函数应该采用 JSONObject。
  • 只需就地替换 JSON 元素。
  • 或者,如果您想展平元素并将它们收集到 aMap中,则预先实例化Map并将其传递给递归函数。

推荐阅读