使用TJSONIterator解析JSON rates对象,TListView仅显示一项的解决方法
解决TJSONIterator解析JSON并在TListView显示不全的问题
问题场景
需要解析以下JSON数据中的rates对象,通过TJSONIterator的Next、Recurse、Return方法提取汇率数据,并在TListView组件中完整展示所有汇率项,但现有代码仅能显示其中一项。
目标JSON数据
{ "meta": { "code": 200, "disclaimer": "Usage subject to terms" }, "response": { "date": "2022-09-16T01:59:00Z", "base": "USD", "rates": { "ADA": 2.13250314, "ZMW": 15.57878043, "ZWD": 361.9, "ZWL": 604.11755006 } } }
用户原有代码
ListView1.Items.Clear; ListView1.Items.BeginUpdate; try oItem := ListView1.Items.Add; try while True do begin while LIterator.Next do if LIterator.&Type in [TJsonToken.StartObject, TJsonToken.StartArray] then begin // Iterate into Rates object and display all the Ccies + Values LIterator.Recurse; LIterator.Next('rates'); LIterator.Recurse; while LIterator.Next do begin LIterator.Recurse; oItem.Text := LIterator.Key {+': '+ LIterator.AsValue.ToString}; end; end; if LIterator.InRecurse then LIterator.Return else Break; end; finally LIterator.Free; end; finally ListView1.Items.EndUpdate; end;
问题原因
- ListViewItem复用问题:仅在循环外创建了一个
oItem,后续循环中不断修改该Item的Text属性,最终只保留最后一次赋值的内容。 - 迭代逻辑混乱:嵌套循环和递归操作冗余,没有正确定位到
rates对象后进行有序遍历,导致迭代流程异常,无法遍历所有键值对。
修正后的代码
ListView1.Items.Clear; ListView1.Items.BeginUpdate; try // 定位到response对象 while LIterator.Next do begin if LIterator.Key = 'response' then begin LIterator.Recurse; // 在response内定位到rates对象 while LIterator.Next do begin if LIterator.Key = 'rates' then begin LIterator.Recurse; // 遍历rates下的所有键值对 while LIterator.Next do begin // 每次循环创建新的ListViewItem var oItem := ListView1.Items.Add; oItem.Text := Format('%s: %.8f', [LIterator.Key, LIterator.AsDouble]); end; // 退出rates对象的递归 LIterator.Return; Break; end; end; // 退出response对象的递归 LIterator.Return; Break; end; end; finally LIterator.Free; ListView1.Items.EndUpdate; end;
代码说明
- 简化迭代流程:逐层定位到
response→rates对象,避免无意义的嵌套循环。 - 每次遍历
rates的键值对时,创建新的TListViewItem,确保每个汇率项都能独立显示。 - 使用
Format方法格式化键值对,同时保留汇率的精度。
内容的提问来源于stack exchange,提问作者LegitLearner
相关产品推荐
相关产品推荐

