如何按名称从嵌套JSON数组中取值?
嵌套JSON数据访问与指定Key内容提取(Pascal/Delphi)
一、纠正错误的.Get用法
Delphi原生System.JSON单元的TJSONObject.Get方法不支持点分隔的路径(如'meta_data.94.key'),也不支持多数组参数的写法。访问嵌套JSON必须逐层转换对象/数组类型,以下是正确写法示例:
假设meta_data是数组,要访问索引94元素的key值:
var ParentObj, ItemObj: TJSONObject; MetaDataArr: TJSONArray; KeyValue: string; begin // 从根数组获取一级对象 ParentObj := (JSONValue as TJSONArray).Items[i] as TJSONObject; // 提取meta_data对应的数组 MetaDataArr := ParentObj.GetValue<TJSONArray>('meta_data'); // 获取数组中索引94的对象 ItemObj := MetaDataArr.Items[94] as TJSONObject; // 提取key值 KeyValue := ItemObj.GetValue<string>('key'); end;
如果meta_data是对象("94"是字符串键),则调整为:
ItemObj := ParentObj.GetValue<TJSONObject>('meta_data').GetValue<TJSONObject>('94');
二、提取指定Key(bm_psi_bulk_prices)下的所有子内容
根据你提供的JSON片段,bm_psi_bulk_prices是嵌套对象(键为"1"、"2"这类字符串,对应价格条目)。要遍历其下所有子内容,可按以下步骤实现:
var RootArr: TJSONArray; ItemObj, BulkPricesObj, PriceItem: TJSONObject; I: Integer; PriceKey: string; begin RootArr := JSONValue as TJSONArray; // 遍历根数组中的每个对象 for I := 0 to RootArr.Count - 1 do begin ItemObj := RootArr.Items[I] as TJSONObject; // 安全检查并提取目标对象 if ItemObj.TryGetValue<TJSONObject>('bm_psi_bulk_prices', BulkPricesObj) then begin // 遍历所有价格条目(数量不固定) for PriceKey in BulkPricesObj.Properties do begin PriceItem := BulkPricesObj.GetValue<TJSONObject>(PriceKey); // 提取子字段,示例:获取bulk_price Writeln('区间标识:', PriceKey); Writeln('批发价格:', PriceItem.GetValue<string>('bulk_price')); // 其他字段可按相同方式提取 end; // 若只需第一个匹配项,可在此添加break; end; end; end;
关键说明
- 使用
TryGetValue<T>可以安全检测目标Key是否存在,避免强制转换引发的异常; TJSONObject.Properties会返回对象所有键的集合,适合处理数量不固定的子内容;- 如果
bm_psi_bulk_prices是数组而非对象,只需将TJSONObject替换为TJSONArray,通过索引遍历Items即可。
三、实用技巧
- 优先使用类型安全的
GetValue<T>/TryGetValue<T>,替代直接as强制转换; - 处理前先明确JSON结构(数组/对象、键的类型),可借助在线JSON格式化工具辅助分析;
- 原生
System.JSON足以应对大多数场景,复杂需求可考虑第三方库(如SuperObject)。
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

