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

使用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;

问题原因

  1. ListViewItem复用问题:仅在循环外创建了一个oItem,后续循环中不断修改该Item的Text属性,最终只保留最后一次赋值的内容。
  2. 迭代逻辑混乱:嵌套循环和递归操作冗余,没有正确定位到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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:15:39