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
代码说明
- 简化JSON解析:直接从
jsonData获取data数组,无需额外转字符串再解析,减少冗余操作。 - 处理动态键层级:
- 第一层遍历
cost对象的所有属性,每个属性的键对应costingid,值是包含多个costid的节点。 - 第二层遍历每个
costing节点下的属性,每个属性的键对应costid,值就是包含目标字段的对象。
- 第一层遍历
- 字段提取:从最内层的
JObject直接通过SelectToken提取所需字段,无需依赖动态键名称。
内容的提问来源于stack exchange,提问作者Lydia
相关产品推荐
相关产品推荐

