英文:
Flattening multidimensional JSON in JAVA
问题
{
"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 code snippet:
JSONObject output;
try {
output = new JSONObject(userJsonAsString);
JSONArray users = output.getJSONArray("users");
for (int i = 0; i < users.length(); i++) {
JSONObject user = users.getJSONObject(i);
JSONArray identities = user.getJSONArray("identities");
for (int j = 0; j < identities.length(); j++) {
JSONObject flatUser = new JSONObject(user, JSONObject.getNames(user));
JSONObject identity = identities.getJSONObject(j);
flatUser.put("signInType", identity.getString("signInType"));
flatUser.put("issuerAssignedId", identity.getString("issuerAssignedId"));
System.out.println(flatUser);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
Flat JSON result (for each user):
{
"extension_user_type": "user",
"extension_locale": "en-GB",
"extension_timezone": "VET",
"displayName": "Sharad Dutta",
"givenName": "",
"surname": "",
"extension_tenant": "EG12345",
"signInType": "emailAddress",
"issuerAssignedId": "kkr007@gmail.com"
}
{
"extension_user_type": "user",
"extension_locale": "en-GB",
"extension_timezone": "VET",
"displayName": "Sharad Dutta",
"givenName": "",
"surname": "",
"extension_tenant": "EG12345",
"signInType": "emailAddress",
"issuerAssignedId": "kkr007@gmail.com"
}
英文:
I have a JSON which looks like this,
{
"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"
}
]
}
I am writing a Java code where I am parsing this Multidimensional JSON to FLAT JSON. If you look closely, the JSON is wrapped in a "users" wrapper and then has couple of users as objects. For each user, there is a field called "identifiers" which is again a wrapper.
I want to flat this JSON, I have written a code but it is leaving a JSON blob for identifiers, for non nested it is working fine
JSONObject output;
try {
output = new JSONObject(userJsonAsString);
JSONArray docs = output.getJSONArray("users");
System.out.println(docs);
This is giving me below output, however i still have to flat inner wrapper "identifiers"
[
{
"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"
}
]
This is what I need,
{
"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"
}
I have to then parse this to CSV, which I know how, I just need to flat this further. Any help will be appreciated. I tried looking around, but a lot of them were using external dependencies.
//UPDATE
{
"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"
}
When I tried @Jakub solution, I am getting the flat JSON, however it is not iterating for all the users. Just one!(I am guessing the last user only)
答案1
得分: 1
你可以遍历 JSON,只需将“叶子节点”存储在映射中。
注意:采用此方法,基本类型的数组会转换为数组中的最后一个值,但这是您描述的内容
类似于以下代码:
void flatJson() throws JSONException {
JSONObject object = new JSONObject(userJsonAsString); // 这是您的输入
Map<String, Object> flatKeyValue = new HashMap<>();
readValues(object, flatKeyValue);
System.out.println(new JSONObject(flatKeyValue)); // 这是扁平化的结果
}
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);
}
}
英文:
You can traverse the json and just store the "leafs" in map.
Note: array of primitives will turn into the last value in the array with this approach, but that's what you described
Something like this:
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);
}
}
答案2
得分: 1
请尝试以下方法,这将为用户和标识符(类似于扁平文件)提供逗号分隔的格式,
public static void main(String[] args) throws JSONException, ParseException {
String userJsonFile = "path to your JSON";
final StringBuilder sBuild = new StringBuilder();
final StringBuilder sBuild2 = new StringBuilder();
try {
String userJsonAsString = "将您的 JSON 转换为字符串并存储在变量中";
} catch (Exception e1) {
e1.printStackTrace();
}
JSONParser jsonParser = new JSONParser();
JSONObject output = (JSONObject) jsonParser.parse(userJsonAsString);
try {
JSONArray docs = (JSONArray) output.get("users");
Iterator<Object> iterator = docs.iterator();
while (iterator.hasNext()) {
JSONObject userEleObj = (JSONObject) iterator.next();
JSONArray nestedIdArray = (JSONArray) userEleObj.get("identities");
Iterator<Object> nestIter = nestedIdArray.iterator();
while (nestIter.hasNext()) {
JSONObject identityEleObj = (JSONObject) nestIter.next();
identityEleObj.keySet().forEach(key -> sBuild2.append(identityEleObj.get(key) + ","));
userEleObj.keySet().forEach(key -> {
if (StringUtils.equals((CharSequence) key, "identities")) {
sBuild.append(sBuild2.toString());
sBuild2.replace(0, sBuild2.length(), "");
} else {
sBuild.append(userEleObj.get(key) + ",");
}
});
}
sBuild.replace(sBuild.lastIndexOf(","), sBuild.length(), "\n");
}
System.out.println(sBuild);
} catch (Exception e) {
e.printStackTrace();
}
}
英文:
Please try the below approach, this will give you a comma separated format for both user and identifier (flat file per se),
public static void main(String[] args) throws JSONException, ParseException {
String userJsonFile = "path to your JSON";
final StringBuilder sBuild = new StringBuilder();
final StringBuilder sBuild2 = new StringBuilder();
try {
String userJsonAsString = convert your JSON to string and store in var;
} catch (Exception e1) {
e1.printStackTrace();
}
JSONParser jsonParser = new JSONParser();
JSONObject output = (JSONObject) jsonParser.parse(userJsonAsString);
try {
JSONArray docs = (JSONArray) output.get("users");
Iterator<Object> iterator = docs.iterator();
while (iterator.hasNext()) {
JSONObject userEleObj = (JSONObject)iterator.next();
JSONArray nestedIdArray = (JSONArray) userEleObj.get("identities");
Iterator<Object> nestIter = nestedIdArray.iterator();
while (nestIter.hasNext()) {
JSONObject identityEleObj = (JSONObject)nestIter.next();
identityEleObj.keySet().stream().forEach(key -> sBuild2.append(identityEleObj.get(key) + ","));
userEleObj.keySet().stream().forEach(key -> {
if (StringUtils.equals((CharSequence) key, "identities")) {
sBuild.append(sBuild2.toString());
sBuild2.replace(0, sBuild2.length(), "");
} else {
sBuild.append(userEleObj.get(key) + ",");
}
});
}
sBuild.replace(sBuild.lastIndexOf(","), sBuild.length(), "\n");
}
System.out.println(sBuild);
} catch (Exception e) {
e.printStackTrace();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论