簡體   English   中英

遞歸解析JSON對象-Java

[英]Parse JSON object recursively - Java

我有一個帶對象列表的JSON,列表中的任何項目都可以具有null或與鍵值相同的對象。 我正在尋找一種解析json以獲得最終結果的更快方法。 數據結構看起來像-

[
    {
        "firstName": "Bruce",
        "familyMembers": null
    },
    {
        "firstName": "Gates Family",
        "familyMembers": [
            {
                "firstName": "Bill",
                "familyMembers": null
            },
            {
                "firstName": "Steve",
                "familyMembers": null
            }
        ]
    },
    {
        "firstName": "Lee",
        "familyMembers": null
    },
    {
        "firstName": "Chan",
        "familyMembers": null
    }
]

輸出應為set =(“ Bruce”,“ Bill”,“ Steve”,“ Lee”,“ Chan”)。

我正在尋找用Java做到這一點的最佳方法,這樣我就不會因為陷入這個解析地獄而增加響應時間。 感謝您的時間。

嘗試我的遞歸實現。

public static void jsonArrayToSet(JSONArray jAry, Set<String> result, String targetKey, String subArrayKey, boolean includeNode){
    try {
        for (int i = 0; i < jAry.length(); i++) {
            JSONObject jObj = jAry.getJSONObject(i);
            boolean hasSubArray = false;
            JSONArray subArray = null;
            if(jObj.has(subArrayKey)){
                Object possibleSubArray = jObj.get(subArrayKey);
                if(possibleSubArray instanceof JSONArray){
                    hasSubArray = true;
                    subArray = (JSONArray) possibleSubArray;
                }
            }
            if(hasSubArray){
                if(includeNode){
                    result.add(jObj.getString(targetKey));
                }
                jsonArrayToSet(subArray, result, targetKey, subArrayKey, includeNode);
            } else {
                result.add(jObj.getString(targetKey));
            }
        }
    } catch (JSONException e){
        e.printStackTrace();
    }
}

jAry :源JSONArray

result :您要寫入的Set

targetKey :映射到要添加到result的條目的鍵。

subArrayKey :映射到子JSONArray的密鑰。

includeNode :當當前JSONOnject是包含子數組的節點時,是否將其添加到result

您可以致電:

jsonArrayToSet(yourJsonArray, yourSet, "firstName", "familyMembers", false);

如我的評論中所述。

您的第一個問題是JSON文件中的內容。 根據標准,應使用一組{}將其包裹起來。

{ 
    "members": [
        {
            "firstName": "Bruce",
            "familyMembers": null
        },
        {
            "firstName": "Gates Family",
            "familyMembers": [
                {
                    "firstName": "Bill",
                    "familyMembers": null
                },
                {
                    "firstName": "Steve",
                    "familyMembers": null
                }
            ]
        },
        {
            "firstName": "Lee",
            "familyMembers": null
        },
        {
            "firstName": "Chan",
            "familyMembers": null
        }
    ]
}

另外,我認為值“ Gates Family”應該成為輸出的一部分嗎? 由於它位於“名字”屬性下。

無論如何,這是基於org.json庫的我的解決方案。 它還使用GoggleGSon庫,在庫中我使用它來讀取JSON文件。

import org.json.*;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Charsets;
import com.google.common.io.Files;

public class solution {

    public static final String JSON_DATA_FILE_PATH = "./data/source_37848106.json";

    private static boolean hasMoreFamilyName(JSONObject json) {
        return json.has("familyMembers") && json.get("familyMembers") != JSONObject.NULL;
    }

    private static void trackFirstName(Map<String, Integer> nameTracker, JSONObject json) {
        if (!nameTracker.containsKey(json.getString("firstName"))) {
            nameTracker.put(json.getString("firstName"), /*DUMMY VALUE =*/1);
        }
    }

    private static void getNames(Map<String,Integer> nameTracker, JSONArray jsonArr) {
        for (int i = 0; i< jsonArr.length(); i++) {
            JSONObject item = jsonArr.getJSONObject(i);
            if (hasMoreFamilyName(item)) {
                getNames(nameTracker, item.getJSONArray("familyMembers"));
            }
            trackFirstName(nameTracker, item);
        }
    }

    public static void main(String[] args) {
        Map<String, Integer> nameTracker = new HashMap<>();

        try {
            String text = Files.toString(new File(JSON_DATA_FILE_PATH), Charsets.UTF_8);
            JSONObject json = new JSONObject(text);
            getNames(nameTracker, json.getJSONArray("members"));
        }
        catch (Exception ex) {
            System.out.println("Something is wrong.");
        }

        for (Map.Entry<String,Integer> entry : nameTracker.entrySet()) {
        System.out.println(entry.getKey());
    }
}

您可以使用在jackson-databind-2.6.5.jar中定義的ObjectMapper

用類似json模式的字段定義一個Java類,然后像這樣綁定它們:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;   

 ObjectMapper objectMapper = new ObjectMapper();
 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
 Family family=objectMapper.readValue(jsonString, Family.class);

現在,您將擁有一個類似於json字符串模式的java對象,並且可以按照自己喜歡的方式打印它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM