如何在 Android kotlin、Moshi 和 Retrofit 中使用动态键解析嵌套 JSON?

Mao*_*dad 6 android kotlin kotlin-android-extensions moshi retrofit2

如何在 Android kotlin、Moshi 和 Retrofit 中使用NESTED动态键解析嵌套 JSON ?

我从alpha-vantage得到这个 JSON 。

格式示例:

{
    "Meta Data": {
        "1. Information": "Intraday (15min) open, high, low, close prices and volume",
        "2. Symbol": "AAME",
        "3. Last Refreshed": "2019-11-18 16:00:00",
        "4. Interval": "15min",
        "5. Output Size": "Compact",
        "6. Time Zone": "US/Eastern"
     },
    "Time Series (15min)": {//Dynamic - > Time Series (5min) / Time Series (30min)
        "2019-11-18 16:00:00": {//Dynamic
            "1. open": "1.6700",
            "2. high": "1.6700",
            "3. low": "1.5700",
            "4. close": "1.5700",
            "5. volume": "1521"
        },
        "2019-11-18 15:45:00": {//Dynamic
            "1. open": "1.6600",
            "2. high": "1.7400",
            "3. low": "1.6600",
            "4. close": "1.7400",
            "5. volume": "355"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用自定义适配器,但找不到用它解析双嵌套动态键的方法。现在我使用手动解析:

fun convertJsonToItemDetails(jso: JSONObject) {
    val meta: JSONObject? = jso.optJSONObject("Meta Data")
    var metaData: ItemMetaData? = null
    meta?.apply {
        val information = optString("1. Information")
        val symbol = optString("2. Symbol")
        val lastRefreshed = optString("3. Last Refreshed")
        val interval = optString("4. Interval")
        val outputSize = optString("5. Output Size")
        val timeZone = optString("6. Time Zone")
        metaData =
            ItemMetaData(information, symbol, lastRefreshed, interval, outputSize, timeZone)
    }
    if (metaData == null) {
        //TODO return error object
        return
    }

    val timeSeriesJSON = jso.optJSONObject("Time Series (${metaData?.interval})")
    val timeSeires = HashMap<String, IntervalOutput>()
    if (timeSeriesJSON == null) {
        //TODO return error object
        return
    }
    for (key in timeSeriesJSON.keys()) {
        val intervalOutPutJSON = timeSeriesJSON.getJSONObject(key)
        val open = intervalOutPutJSON.getString("1. open")
        val high = intervalOutPutJSON.getString("2. high")
        val low = intervalOutPutJSON.getString("3. low")
        val close = intervalOutPutJSON.getString("4. close")
        val volume = intervalOutPutJSON.getString("5. volume")
        timeSeires[key] = IntervalOutput(open, high, low, close, volume)
    }
    val itemDetails = ItemDetails(metaData, timeSeires)
    _itemDetails.value = itemDetails
}
Run Code Online (Sandbox Code Playgroud)

Gun*_*gar 0

只要将你的 json 字符串传递给这个方法,它就一定可以工作。

\n\n
private void parseJson(String jsonString) {\n    try {\n        //  pass your response json string here\n        JSONObject object = new JSONObject(jsonString);\n\n        Iterator<String> it = object.keys();\n        while (it.hasNext()) {\n            String key = it.next();\n            try {\n                if (object.get(key) instanceof JSONObject) {\n                    Log.e("Main OBJ", key);\n                    JSONObject object2 = object.getJSONObject(key);\n                    Iterator<String> it2 = object2.keys();\n                    while (it2.hasNext()) {\n                        String key2 = it2.next();\n                        if (object2.get(key2) instanceof JSONObject) {\n                            Log.e("Sub OBJ", key2);\n                            JSONObject object3 = object2.getJSONObject(key2);\n                            Iterator<String> it3 = object3.keys();\n                            while (it3.hasNext()) {\n                                String key4 = it3.next();\n                                Log.e("Values", key4);\n                            }\n                        } else {\n                            Log.e("Values", object2.getString(key2));\n                        }\n                    }\n\n                } else {\n                    System.out.println(key + ":" + object.getString(key));\n                }\n            } catch (Throwable e) {\n                try {\n                    System.out.println(key + ":" + object.getString(key));\n                } catch (Exception ee) {\n                    ee.printStackTrace();\n                }\n                e.printStackTrace();\n            }\n        }\n\n    } catch (JSONException e) {\n        e.printStackTrace();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
Main\xc2\xa0OBJ: Meta Data\nValues: Intraday (15min) open, high, low, close prices and volume\nValues: AAME\nValues: 2019-11-18 16:00:00\nValues: 15min\nValues: Compact\nValues: US/Eastern\nMain\xc2\xa0OBJ: Time Series (15min)\nSub\xc2\xa0OBJ: 2019-11-18 16:00:00\nValues: 1. open\nValues: 2. high\nValues: 3. low\nValues: 4. close\nValues: 5. volume\nSub\xc2\xa0OBJ: 2019-11-18 15:45:00\nValues: 1. open\nValues: 2. high\nValues: 3. low\nValues: 4. close\nValues: 5. volume\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这不是正确的答案。您可以使用 Map 解析动态键。这里的问题是嵌套的动态键。另外,就像这里的其他人所说的那样,其他库也是可能的(我没有检查)。 (2认同)