【问题标题】:delphi parse jsonarray with System.JSONdelphi 使用 System.JSON 解析 jsonarray
【发布时间】:2016-01-09 05:46:00
【问题描述】:

使用 Delphi XE8 的 System.JSON,我无法解析 jsonarray

Json 示例:

{
    "data":{
        "current_condition":[
            {
                "cloudcover":"0",
                "FeelsLikeC":"-9",
                "FeelsLikeF":"15",
                "humidity":"93",
                "observation_time":"04:10 AM",
                "precipMM":"0.0",
                "pressure":"1007",
                "temp_C":"-6",
                "temp_F":"21",
                "visibility":"10",
                "weatherCode":"113",
                "weatherDesc":[
                    
                ],
                "weatherIconUrl":[
                    
                ],
                "winddir16Point":"SE",
                "winddirDegree":"130",
                "windspeedKmph":"7",
                "windspeedMiles":"4"
            }
        ]
    }
}

使用代码:

memores: TStringList;
currcond: TJSONObject;

memores2.Text := http.Get ('url');
JSONObject := TJSONObject.ParseJSONValue(memores2.Text) as TJSONObject;
Memores1.add('current_condition');
JSONObject2 := JSONObject.GetValue('data')   as TJSONObject;
arrayjson := JSONObject2.ParseJSONValue('current_condition')  as TJSONArray;
currcond := arrayjson.Items[0] as TJSONObject;
memores1.Add((currcond.GetValue('cloudcover').Value));

【问题讨论】:

  • 函数 TJSONArray.GetCount 中的错误:整数;如果(FElements = nil)或(FElements.Count = 0)则开始,然后退出(0);结果:= FElements.Count;结尾; (FElements = nil)
  • 完成 JSONObject2:=JSONObject.GetValue('data') as TJSONObject; arrayjson:=JSONObject2.GetValue('current_condition') as TJSONArray; currcond := arrayjson.Items[0] 作为 TJSONObject; // 解析 currcond/// memores1.Add((currcond.GetValue('cloudcover').Value));

标签: json delphi parsing system.json


【解决方案1】:
arrayjson:=JSONObject2.ParseJSONValue('current_condition')  as TJSONArray;

这会尝试解析文本

current_condition

好像是 JSON。它不是。因此arrayjson 是nil,因此会产生运行时错误。将该行代码替换为:

arrayjson := JSONObject2.GetValue('current_condition') as TJSONArray;

例如这个程序:

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.JSON;

const
  Text =
    '{ "data":{ "current_condition":[ { "cloudcover":"0", "FeelsLikeC":"-9", "FeelsLikeF":"15", "humidity":"93", ' +
    '"observation_time":"04:10 AM", "precipMM":"0.0", "pressure":"1007", "temp_C":"-6", "temp_F":"21", "visibility":"10", ' +
    '"weatherCode":"113", "weatherDesc":[], "weatherIconUrl":[], "winddir16Point":"SE", "winddirDegree":"130", "windspeedKmph":"7", "windspeedMiles":"4" } ] } }';

procedure Main;
var
  JSONObject, JSONObject2, currcond: TJSONObject;
  arrayjson: TJSONArray;
begin
  JSONObject := TJSONObject.ParseJSONValue(Text) as TJSONObject;
  JSONObject2 := JSONObject.GetValue('data') as TJSONObject;
  arrayjson := JSONObject2.GetValue('current_condition') as TJSONArray;
  currcond := arrayjson.Items[0] as TJSONObject;
  Writeln(currcond.GetValue('observation_time').Value);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

输出

04:10 AM

在上面的简单代码中,我没有尝试添加错误检查。你应该这样做。

【讨论】:

    【解决方案2】:

    作为提供的解决方案的替代方案,但使用mORMot:

    {$APPTYPE CONSOLE}
    
    uses
      SynCommons;
    
    const
        Text =  '{ "data":{ "current_condition":[ { "cloudcover":"0", "FeelsLikeC":"-9", "FeelsLikeF":"15", "humidity":"93", ' +
                '"observation_time":"04:10 AM", "precipMM":"0.0", "pressure":"1007", "temp_C":"-6", "temp_F":"21", "visibility":"10", ' +
                '"weatherCode":"113", "weatherDesc":[], "weatherIconUrl":[], "winddir16Point":"SE", "winddirDegree":"130", "windspeedKmph":"7", "windspeedMiles":"4" } ] } }';
    
    var Data , CurrentConditionArray : TDocVariantData;
        Current_Condition , Json : Variant;
    begin
      Json := _Json(Text);
      // Alternative 1
      Current_Condition := Json.data.current_condition._(0);
      Assert( Current_Condition.observation_time = '04:10 AM' );
    
      // Alternative 2 slightly faster
      Data := TDocVariantData(Json).O['data']^;
      CurrentConditionArray := Data.A['current_condition']^;
      Current_Condition := CurrentConditionArray.Values[0];
      Assert( TDocVariantData(Current_Condition).Value['precipMM'] = '0.0' );
    end.
    

    这应该适用于 Delphi 7 到 10.4。请在amazing documentation

    中找到更多详细信息和替代方案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多