android - 如何在 Android kotlin、Moshi 和 Retrofit 中解析带有动态键的嵌套 JSON?

标签 android kotlin retrofit2 kotlin-android-extensions moshi

如何在 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"
        }
    }
}

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

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
}

最佳答案

使用JSONObject keys()获取动态键,然后迭代每个特定键以获得动态值。

打印第一层的所有 JSONObject 的非常简短的内容如下所示。

var dynamicJSON: String = {
    "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"
        }
    }
}  

然后,您必须开始将其解析为 JSONObject,然后进一步对 JSONObject “元数据”“时间序列(15 分钟)”进行相同的过程

val dynamicjson: JSONObject = JSONObject(dynamicJSON)
val keys: Iterator<*> = dynamicjson.keys()

while (keys.hasNext()) { // loop to get the dynamic key
   val currentDynamicKey = keys.next() as String
   // get the value of the dynamic key
   val currentDynamicValue: JSONObject = dynamicjson.getJSONObject(currentDynamicKey)
   // do something here with the value... or either make another while loop to Iterate further

   Log.e("JSON Value", currentDynamicValue.toString())
}

当我执行代码时,输​​出如下所示:

2019-12-12 15:21:08.399 19798-19798/com.animusabhi.dynamicjsonparsing E/JSON Value: {"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"}

2019-12-12 15:21:09.158 19798-19798/com.animusabhi.dynamicjsonparsing E/JSON Value{"2019-11-18 16:00:00":{"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":{"1. open":"1.6600","2. high":"1.7400","3. low":"1.6600","4. close":"1.7400","5. volume":"355"}}

检查一下,如果不起作用请告诉我。

关于android - 如何在 Android kotlin、Moshi 和 Retrofit 中解析带有动态键的嵌套 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58936702/

相关文章:

android - 如何用 rxjava2 取消 Observable.timer?

java - 如何通过改造调用处理来自网络的错误

android - 我怎样才能实现这种 View ??(在 ListView 中)

android - 从其他类使用时,lateinit 属性绑定(bind)尚未初始化

组合中的 Spring 验证

Android Compose 显示和隐藏键盘

android - 如何对齐两个按钮彼此相邻?

android - NFC 插件在 Eclipse 中不起作用

kotlin - 如何使用 spqr 从查询根节点中排除突变?

android - 改造日志拦截器异常