You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中如何反序列化并遍历JSON数组及嵌套数据

嵌套JSON动态键数据提取问题

问题背景

原始JSON数据

{
    "TNS-API-KEY": "ABCD134EFG456HIJK678LMNOP",
    "docno": "35829",
    "idtns": "abc12345",
    "action": "6",
    "reason": "test -test",
    "userid": "450",
    "data": [
        {
            "pr": "0222/ATL/MIX/01/2021",
            "idpr": "13562",
            "cost": {
                "26217": {
                    "50662": {
                        "costingid": "26217",
                        "costid": "50662",
                        "gpro": "SSM",
                        "dbp": "18000",
                        "ppn": "0"
                    },
                    "50664": {
                        "costingid": "26217",
                        "costid": "50664",
                        "gpro": "SBL",
                        "dbp": "40500",
                        "ppn": "0"
                    }
                }
            }
        },
        {
            "pr": "123/AB/MIX/07/2022",
            "idpr": "17461",
            "cost": {
                "34876": {
                    "66194": {
                        "costingid": "34876",
                        "costid": "66194",
                        "gpro": "CCL",
                        "dbp": "1000000",
                        "ppn": "110000.00"
                    }
                },
                "34877": {
                    "66195": {
                        "costingid": "34877",
                        "costid": "66195",
                        "gpro": "TB",
                        "dbp": "2000000",
                        "ppn": "220000.00"
                    }
                }
            }
        }
    ]
}

需求说明

需要从每个PR条目里提取以下字段:

  • costingid
  • costid
  • gpro
  • dbp
  • ppn

现有代码

已经能获取到data数组及PR编号,代码如下:

Dim jsonData As JObject = JObject.Parse(json)
Dim data As String = jsonData.SelectToken("data").ToString()
Dim jsonArray As JArray = JArray.Parse(jsonData.SelectToken("data").ToString)

For Each item As JObject In jsonArray
    Dim pr As String = (item.SelectToken("pr").ToString)
Next

疑问

如何获取嵌套在内层的数据?由于cost下的键是动态的(比如26217、34876这类无固定名称的键),不知道怎么进行内层循环处理。


解决方案

针对动态键的嵌套结构,可以通过遍历JObject的Properties来处理每一层动态节点,完整代码如下:

Imports Newtonsoft.Json.Linq

' 解析JSON
Dim jsonData As JObject = JObject.Parse(json)
Dim jsonArray As JArray = jsonData.SelectToken("data")

' 遍历每个PR条目
For Each prItem As JObject In jsonArray
    Dim prNumber As String = prItem.SelectToken("pr").ToString()
    Console.WriteLine($"PR编号: {prNumber}")
    
    ' 获取cost节点
    Dim costObj As JObject = prItem.SelectToken("cost")
    If costObj IsNot Nothing Then
        ' 遍历第一层动态键(对应costingid的键)
        For Each costingProp As JProperty In costObj.Properties()
            ' 获取costing节点下的所有cost子节点
            Dim costSubObj As JObject = costingProp.Value
            ' 遍历第二层动态键(对应costid的键)
            For Each costProp As JProperty In costSubObj.Properties()
                ' 提取目标字段
                Dim costDetail As JObject = costProp.Value
                Dim costingid As String = costDetail.SelectToken("costingid").ToString()
                Dim costid As String = costDetail.SelectToken("costid").ToString()
                Dim gpro As String = costDetail.SelectToken("gpro").ToString()
                Dim dbp As String = costDetail.SelectToken("dbp").ToString()
                Dim ppn As String = costDetail.SelectToken("ppn").ToString()
                
                ' 输出或处理提取到的数据
                Console.WriteLine($"  costingid: {costingid}, costid: {costid}, gpro: {gpro}, dbp: {dbp}, ppn: {ppn}")
            Next
        Next
    End If
Next

代码说明

  1. 简化JSON解析:直接从jsonData获取data数组,无需额外转字符串再解析,减少冗余操作。
  2. 处理动态键层级:
    • 第一层遍历cost对象的所有属性,每个属性的键对应costingid,值是包含多个costid的节点。
    • 第二层遍历每个costing节点下的属性,每个属性的键对应costid,值就是包含目标字段的对象。
  3. 字段提取:从最内层的JObject直接通过SelectToken提取所需字段,无需依赖动态键名称。

内容的提问来源于stack exchange,提问作者Lydia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:50:30