私はJSONを初めて使用するので、JSONを解析してその内容の一部をListViewに表示する必要があるこのプロジェクトを手にしています。問題は、私が読んだドキュメントがJSON配列を含むJSONオブジェクトを扱っていることですが、私の場合はネストされたオブジェクトを扱っています。話を短くするために、これが要約です。私はDBXJSONでDelphi XE2を使用しています。サーバーにいくつかの値を投稿すると、次のようなJSONオブジェクトで応答します。
{
"products": {
"Men's Sneakers": {
"instock": false,
"size": "423",
"manufacturer": "Adidas",
"lastcheck": "20120529"
},
"Purse": {
"instock": true,
"size": "not applicable",
"manufacturer": "Prada",
"lastcheck": "20120528"
},
"Men's Hood": {
"instock": false,
"size": "M",
"manufacturer": "Generic",
"lastcheck": "20120529"
}
},
"total": 41,
"available": 30
}
私が達成したかったことは、1つのサブアイテム(メーカー)とともに、各アイテム(つまり、財布)を解析し、リストビューのキャプションとして追加することでした。 JSON文字列を引数として取るプロシージャを作成し、JSONオブジェクトを作成しましたが、ネストされたオブジェクトをさらに解析する方法がわかりません。
procedure TForm1.ParseString(const AString: string);
var
json : TJSONObject;
jPair : TJSONPair;
jValue : TJSONValue;
jcValue : TJSONValue;
l,i : Integer;
begin
json := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(AString),0) as TJSONObject;
try
//get the pair to evaluate in this case the index is 1
jPair := json.Get(1);
{further process the nested objects and adding them to the listview}
finally
json.Free;
end;
end;
任意の提案をいただければ幸いです。 DelphiでJSONのインとアウトを無駄にしようとしてかなりの時間を失いました。
ありがとう、スフィンクス
このサンプルをお試しください
{$APPTYPE CONSOLE}
{$R *.res}
uses
DBXJSON,
System.SysUtils;
Const
StrJson=
'{'+
' "products": {'+
' "Men''s Sneakers": {'+
' "instock": false,'+
' "size": "423",'+
' "manufacturer": "Adidas",'+
' "lastcheck": "20120529"'+
' },'+
' "Purse": {'+
' "instock": true,'+
' "size": "not applicable",'+
' "manufacturer": "Prada",'+
' "lastcheck": "20120528"'+
' },'+
' "Men''s Hood": {'+
' "instock": false,'+
' "size": "M",'+
' "manufacturer": "Generic",'+
' "lastcheck": "20120529"'+
' }'+
' },'+
' "total": 41,'+
' "available": 30'+
'}';
procedure ParseJson;
var
LJsonObj : TJSONObject;
LJPair : TJSONPair;
LProducts : TJSONValue;
LProduct : TJSONValue;
LItem : TJSONValue;
LIndex : Integer;
LSize : Integer;
begin
LJsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson),0) as TJSONObject;
try
LProducts:=LJsonObj.Get('products').JsonValue;
LSize:=TJSONArray(LProducts).Size;
for LIndex:=0 to LSize-1 do
begin
LProduct := TJSONArray(LProducts).Get(LIndex);
LJPair := TJSONPair(LProduct);
Writeln(Format('Product Name %s',[LJPair.JsonString.Value]));
for LItem in TJSONArray(LJPair.JsonValue) do
begin
if TJSONPair(LItem).JsonValue is TJSONFalse then
Writeln(Format(' %s : %s',[TJSONPair(LItem).JsonString.Value, 'false']))
else
if TJSONPair(LItem).JsonValue is TJSONTrue then
Writeln(Format(' %s : %s',[TJSONPair(LItem).JsonString.Value, 'true']))
else
Writeln(Format(' %s : %s',[TJSONPair(LItem).JsonString.Value, TJSONPair(LItem).JsonValue.Value]));
end;
end;
finally
LJsonObj.Free;
end;
end;
begin
try
ParseJson;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
これは戻ります
Product Name Men's Sneakers
instock : false
size : 423
manufacturer : Adidas
lastcheck : 20120529
Product Name Purse
instock : true
size : not applicable
manufacturer : Prada
lastcheck : 20120528
Product Name Men's Hood
instock : false
size : M
manufacturer : Generic
lastcheck : 20120529
このサイト は、タイプTJSONValue
についてさらに詳しく説明しています。データがオブジェクトの場合、タイプは TJSONObject
になるため、APIを確認して続行方法を確認してください。
私はペアを反復するために最初に必要なことを信じています(キー名がわからない場合はGetEnumerator
を使用します。それ以外の場合は、多重定義されたGet
を使用します-数値ではなく文字列を渡します)。ペアごとに、キーは単純な文字列(タイプTJSONString
)で、値は任意のTJSONValue
になります。葉に達するまで繰り返します。
例:
products := jPair.Get('products');
purse := products.GetJsonValue().Get('Purse');
purseManuf := purse.GetJsonValue().Get('manufacturer');
...
または、製品がわからない場合:
products := jPair.Get('products');
for prodPair in products.GetEnumerator() do
begin
prodName := prodPair.GetJsonString();
prodObj := prodPair.GetJsonValue();
...
このブログ投稿 は、JSONを変換する非常にモダンでシンプルな方法を示しています。
uses REST.JSON; // Also new System.JSON
procedure TForm1.Button1Click(Sender: TObject);
var
Foo: TFoo;
begin
Foo := TFoo.Create;
try
Foo.Foo := 'Hello World';
Foo.Fee := 42;
Memo1.Lines.Text := TJson.ObjectToJsonString(Foo);
finally
Foo.Free;
end;
Foo := TJson.JsonToObject<TFoo>(Memo1.Lines.Text);
try
Foo.Fee := 100;
Memo1.Lines.Add(TJson.ObjectToJsonString(Foo));
finally
Foo.Free;
end;
end;