首页 > 解决方案 > 在 JAVA 中展平多维 JSON

问题描述

我有一个看起来像这样的 JSON,

{
  "users": [
    {
      "displayName": "Sharad Dutta",
      "givenName": "",
      "surname": "",
      "extension_user_type": "user",
      "identities": [
        {
          "signInType": "emailAddress",
          "issuerAssignedId": "kkr007@gmail.com"
        }
      ],
      "extension_timezone": "VET",
      "extension_locale": "en-GB",
      "extension_tenant": "EG12345"
    },   
    {
      "displayName": "Sharad Dutta",
      "givenName": "",
      "surname": "",
      "extension_user_type": "user",
      "identities": [
        {
          "signInType": "emailAddress",
          "issuerAssignedId": "kkr007@gmail.com"
        }
      ],
      "extension_timezone": "VET",
      "extension_locale": "en-GB",
      "extension_tenant": "EG12345"
    }
  ]
}

我正在编写一个 Java 代码,我正在将这个多维 JSON 解析为 FLAT JSON。如果仔细观察,JSON 被包装在“用户”包装器中,然后有几个用户作为对象。对于每个用户,都有一个称为“标识符”的字段,它又是一个包装器。

我想扁平化这个 JSON,我已经编写了一个代码,但是它为标识符留下了一个 JSON blob,对于非嵌套它工作正常

JSONObject output;
        try {
            output = new JSONObject(userJsonAsString);
            JSONArray docs = output.getJSONArray("users");
            System.out.println(docs);

这给了我下面的输出,但是我仍然必须平整内部包装“标识符”

[
  {
    "extension_timezone": "VET",
    "extension_tenant": "EG12345",
    "extension_locale": "en-GB",
    "identities": [
      {
        "signInType": "emailAddress",
        "issuerAssignedId": "pdhongade007@gmail.com"
      }
    ],
    "displayName": "Sharad Dutta",
    "surname": "",
    "givenName": "",
    "extension_user_type": "user"
  },
  {
    "extension_timezone": "VET",
    "extension_tenant": "EG12345",
    "extension_locale": "en-GB",
    "identities": [
      {
        "signInType": "userName",
        "issuerAssignedId": "pdhongade007"
      }
    ],
    "displayName": "Wayne Rooney",
    "surname": "Rooney",
    "givenName": "Wayne",
    "extension_user_type": "user"
  }
]

这是我需要的

{
    "extension_timezone": "VET",
    "extension_tenant": "EG12345",
    "extension_locale": "en-GB",
    "signInType": "emailAddress",
    "issuerAssignedId": "pdhongade007@gmail.com",
    "displayName": "Sharad Dutta",
    "surname": "",
    "givenName": "",
    "extension_user_type": "user"
  }

然后我必须将其解析为 CSV,我知道如何,我只需要进一步扁平化。任何帮助将不胜感激。我试着环顾四周,但其中很多都在使用外部依赖项。

//更新

{
  "extension_timezone": "VET",
  "extension_tenant": "EG12345",
  "extension_locale": "en-GB",
  "signInType": "userName",
  "displayName": "Wayne Rooney",
  "surname": "Rooney",
  "givenName": "Wayne",
  "issuerAssignedId": "pdhongade007",
  "extension_user_type": "user"
}

当我尝试@Jakub 解决方案时,我得到了平面 JSON,但是它并没有针对所有用户进行迭代。只有一个!(我猜只有最后一个用户)

标签: javaarraysjson

解决方案


您可以遍历 json 并将“叶子”存储在地图中。注意:使用这种方法,原语数组将变成数组中的最后一个值,但这就是你所描述的:)

像这样的东西:

void flatJson() throws JSONException {
    JSONObject object = new JSONObject(userJsonAsString); // this is your input
    Map<String, Object> flatKeyValue = new HashMap<>();
    readValues(object, flatKeyValue);
    System.out.println(new JSONObject(flatKeyValue)); // this is flat
}

void readValues(JSONObject object, Map<String, Object> json) throws JSONException {
    for (Iterator it = object.keys(); it.hasNext(); ) {
        String key = (String) it.next();
        Object next = object.get(key);
        readValue(json, key, next);
    }
}

void readValue(Map<String, Object> json, String key, Object next) throws JSONException {
    if (next instanceof JSONArray) {
        JSONArray array = (JSONArray) next;
        for (int i = 0; i < array.length(); ++i) {
            readValue(json, key, array.opt(i));
        }
    } else if (next instanceof JSONObject) {
        readValues((JSONObject) next, json);
    } else {
        json.put(key, next);
    }
}

推荐阅读