如何在Delphi Xe4中阅读相当简单的JSON文件?

时间:2014-06-28 11:57:57

标签: json delphi delphi-xe4

我已经在这方面挣扎了一段时间,做一些简单的事情似乎花了太长时间。

我有一个这样的文件:

[
 {
  "FirstName": "Oleg",
  "Surname": "Buckley"
 },
 {
  "FirstName": "Amery",
  "Surname": "Mcmillan"
 },
 {
  "FirstName": "Denton",
  "Surname": "Burnett"
....

我希望能够将它们读入我的程序。到目前为止,我已经完成了这个非常小的功能:

function GetGeneratedNames: TArray<string>;
var fileName: TFileName;
  JSONValue, jv: TJSONValue;
  JSONArray: TJSONArray;
  jo: TJSONObject;
  pair: TJSONPair;
begin
  result := nil;
  filename := ExePath + 'Names.json';
    JSONValue :=  TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(TFile.ReadAllText(filename)), 0);
    if JSONValue is TJSONArray then begin
     for jv in (JSONValue as TJSONArray) do begin
       if jv is TJSONObject then begin
         jo := jv as TJSONObject;
         for pair in jo do begin
           Append(result, jo.Value);
         end;
       end;
     end;
   end;
end{ GetGeneratedNames};

麻烦的是,它返回一个空字符串数组。有人能指出我正确的方向吗?

TIA 标记

3 个答案:

答案 0 :(得分:7)

// XE5- version
uses System.SysUtils, Data.DBXJSON, System.IOUtils;

function GetGeneratedNames: TArray<string>;
var
  fileName: TFileName;
  JSONValue, jv: TJSONValue;
begin
  fileName := TPath.Combine(ExePath, 'Names.json');
  JSONValue := TJSONObject.ParseJSONValue(TFile.ReadAllText(fileName));
  try
    if JSONValue is TJSONArray then
    begin
      for jv in TJSONArray(JSONValue) do
      begin
        Append(Result, (jv as TJSONObject).Get('FirstName').JSONValue.Value);
        Append(Result, (jv as TJSONObject).Get('Surname').JSONValue.Value);
      end;
    end;
  finally
    JSONValue.Free;
  end;
end { GetGeneratedNames };

// XE6+ version
uses System.SysUtils, System.JSON, System.IOUtils;

function GetGeneratedNames: TArray<string>;
var
  fileName: TFileName;
  JSONValue, jv: TJSONValue;
begin
  fileName := TPath.Combine(ExePath, 'Names.json');
  JSONValue := TJSONObject.ParseJSONValue(TFile.ReadAllText(fileName));
  try
    if JSONValue is TJSONArray then
    begin
      for jv in TJSONArray(JSONValue) do
      begin
        Append(Result, jv.GetValue<string>('FirstName'));
        Append(Result, jv.GetValue<string>('Surname'));
      end;
    end;
  finally
    JSONValue.Free;
  end;
end { GetGeneratedNames };

答案 1 :(得分:4)

您没有从数组项中读取正确的值 尝试这样的事情:

//...
var
  JSONArr: TJSONArray;
  Item: TJSONValue;
  FirstName, Surname, WholeObject: String;
begin
  //...
  JSONArr := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(TFile.ReadAllText(filename)), 0);
  try
    for Item in JSONArr do
    begin
      // Get the first or last names
      FirstName := (Item as TJSONObject).GetValue('FirstName').Value;
      Surname := (Item as TJSONObject).GetValue('Surname').Value;
      // Get the whole string {"FirstName": "Oleg", "Surname": "Buckley"}
      WholeObject := Item.ToString; 
    end;
  finally
    JSONArr.Free;
  end;
  // do something with them ...
end;

JSON对象包含值对,但它本身没有值,因此您获得空字符串。如果你想要整个对象文本,你应该使用&#34; ToString&#34;方法

如果您碰巧处理大量数据,SuperObjectXSuperObject确实更容易使用和更快。第二个似乎也适用于iOS / Android,虽然我还没有使用它。

答案 2 :(得分:0)

感谢tz和VGeorgiev。以下是代码的最终形式,基于您的:

function GetGeneratedNames: TArray<string>;
var data: TBytes;
    JSONValue, jv: TJSONValue;
    joName: TJSONObject;
    firstName, surname: string;
begin
  result := nil;
  data := TEncoding.ASCII.GetBytes(TFile.ReadAllText(ExePath + 'Names.json'));
  JSONValue := TJSONObject.ParseJSONValue(data, 0);
  for jv in JSONValue as TJSONArray do begin  // Returns TJSONValue
    joName := jv as TJSONObject;
    firstName := joName.Get('FirstName').JSONValue.Value;
    surname := joName.Get('Surname').JSONValue.Value;
    Append(Result, surname + ', ' + firstName);
  end{for};
end{ GetGeneratedNames};