![]() |
JSON iterieren, aber wie?
Moin,
ich stehe hier gerade ein wenig auf dem Schlauch und bräuchte mal eine Hilfestellung. Gegeben ist folgendes JSON:
Code:
Wie kann ich jetzt, in diesem Falkl die sechs Artikel (article) druchiterieren um an die einzelnen Werte zu kommen, über einen kurzen Tipp wäre ich dankbar.
{
"data": [ { "article": { "id": 12472, "sku": "AAXXX165", "name": "Außenspiegel links elektrisch verstellbar Temperatursensor 5 W langer Spiegelarm", "manufacturer": "Originalgerätehersteller (Original Equipment Manufacturer)", "price": 12345.5, "quality": "Ident", "deposit": null, "deposit_article_sku": null, "created_at": "2016-02-13 16:30:43", "updated_at": null, "oe_number": null, "stock": 1, "weight": 3.48, "unit": { "amount": 64.925, "unit": "Stk." }, "dimensions": { "length": [ 0, "mm" ], "width": [ 0, "mm" ], "height": [ 0, "mm" ] }, "important_information": { "hazard_warnings": null } } }, { "article": { "id": 12475, "sku": "AAXXX168", "name": "Außenspiegel links elektrisch verstellbar 16 W langer Spiegelarm", "manufacturer": "Originalgerätehersteller (Original Equipment Manufacturer)", "price": 12345.8, "quality": "Ident", "deposit": null, "deposit_article_sku": null, "created_at": "2016-02-13 16:30:43", "updated_at": null, "oe_number": null, "stock": 91, "weight": 3.48, "unit": { "amount": 64.09, "unit": "Stk." }, "dimensions": { "length": [ 500, "mm" ], "width": [ 400, "mm" ], "height": [ 230, "mm" ] }, "important_information": { "hazard_warnings": null } } }, { "article": { "id": 12476, "sku": "AAXXX169", "name": "Außenspiegel links elektrisch verstellbar Temperatursensor 16W langer Spiegelarm", "manufacturer": "Originalgerätehersteller (Original Equipment Manufacturer)", "price": 12345.5, "quality": "Ident", "deposit": null, "deposit_article_sku": null, "created_at": "2016-02-13 16:30:43", "updated_at": null, "oe_number": null, "stock": 322, "weight": 3.48, "unit": { "amount": 64.925, "unit": "Stk." }, "dimensions": { "length": [ 500, "mm" ], "width": [ 400, "mm" ], "height": [ 230, "mm" ] }, "important_information": { "hazard_warnings": null } } }, { "article": { "id": 22684, "sku": "AAXXX169OE", "name": "Außenspiegel links elektrisch verstellbar Temperatursensor 16W langer Spiegelarm Original", "manufacturer": "Original Ersatzteil (genuine part)", "price": 123456.75, "quality": null, "deposit": null, "deposit_article_sku": null, "created_at": "2016-02-13 16:30:47", "updated_at": null, "oe_number": null, "stock": 1, "weight": 3.5, "unit": { "amount": 190.894, "unit": "Stk." }, "dimensions": { "length": [ 530, "mm" ], "width": [ 500, "mm" ], "height": [ 230, "mm" ] }, "important_information": { "hazard_warnings": null } } }, { "article": { "id": 30970, "sku": "AAXXX169MM", "name": "Außenspiegel links elektrisch verstellbar Temperatursensor 16W langer Spiegelarm Magneti Marelli", "manufacturer": "Marelli Aftermarket Germany GmbH", "price": 123454.26, "quality": null, "deposit": null, "deposit_article_sku": null, "created_at": "2016-08-18 15:47:22", "updated_at": null, "oe_number": null, "stock": 54, "weight": 3.45, "unit": { "amount": 80.004, "unit": "Stk." }, "dimensions": { "length": [ 240, "mm" ], "width": [ 460, "mm" ], "height": [ 520, "mm" ] }, "important_information": { "hazard_warnings": null } } }, { "article": { "id": 41961, "sku": "7870019", "name": "Satz Spiegel rechts & links elektrisch mit Temperatursensor 16 W", "manufacturer": "Bosch/Siemens", "price": 123456.4, "quality": "Ident", "deposit": null, "deposit_article_sku": null, "created_at": "2017-08-15 12:19:24", "updated_at": null, "oe_number": null, "stock": 1, "weight": 6.9, "unit": { "amount": 127.872, "unit": "Stk." }, "dimensions": { "length": [ 0, "mm" ], "width": [ 0, "mm" ], "height": [ 0, "mm" ] }, "important_information": { "hazard_warnings": null } } } ], "meta": { "pagination": { "total": 6, "count": 6, "per_page": 100, "current_page": 1, "total_pages": 1, "links": {} } } } Gruß |
AW: JSON iterieren, aber wie?
Ohne Fehlerbehandlung schnell heruntergetippt:
Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var SL: TStringList; obj: TJSONObject; arr: TJSONArray; i: integer; subobj: TJSONObject; begin obj := nil; SL := TStringList.Create; try SL.LoadFromFile('C:\temp\TestJSON.txt'); // Das JSON aus Deinem Post obj := TJsonObject.ParseJSONValue(SL.Text) as TJSONObject; arr := obj.Values['data'] as TJSONArray; for i := 0 to arr.Count - 1 do begin subobj := (arr.Items[i] as TJSONObject).Values['article'] as TJSONObject; ShowMessage(subobj.Values['sku'].Value); end; finally SL.Free; obj.Free; end; end; |
AW: JSON iterieren, aber wie?
Es gibt folgende Funktion:
Delphi-Quellcode:
Damit kannst du einen JSON-String in ein Objekt umwandeln. Allerdings musst du dafür eine Objektstruktur in Form von Datenklassen haben, welche du als TClass übergeben kannst. Und das System funktioniert nicht mit TList, sondern nur mit Arrays. Ansonsten hat Uwe Raabe (der ist auch hier im Forum vertreten) vor längerer Zeit mal einen Artikel zu dem Thema auf seine Webseite gestellt.
TJson.JsonToObject<TClass>(sJsonString)
![]() Vielleicht kannst du damit mehr anfangen. |
AW: JSON iterieren, aber wie?
Das gegebene ist ein TJsonObject.
Es enthält das TJsonArray mit dem Namen "data". Das enthält mehrere TJsonObject, welche nur eine TJsonObject "article" enthalten. Im Endeffekt gibt es zwei Möglichkeiten:
Das einmal als Beispiel, im Endeffekt wie ein Beitrag weiter oben, nur halt lieber mit einem "Path" anstatt mit Zwischen-Variablen:
Delphi-Quellcode:
program Project1;
uses System.SysUtils, System.JSON; const JSON = '{ ... }'; var jsonObj: TJsonObject; begin jsonObj := TJSONObject.ParseJSONValue(JSON) as TJsonObject; var count := jsonObj.GetValue<TJsonArray>('data').Count; WriteLn('Wir haben ', count, ' Einträge'); for var index := 0 to Pred(count) do begin var path := String.Format('data[%d].article.name', [index]); var articleName := jsonObj.GetValue<String>(path); WriteLn('Artikel: ', articleName); end; ReadLn; end. |
AW: JSON iterieren, aber wie?
@Daddy: Funktioniert! Danke dafür.
@Günther: Funktioniert auch! Danke dafür. @Maliko: Den Blogpost von Uwe werde ich versuchen umzusetzen bzw. zu verstehen. Vielen Dank für Eure Bemühungen. |
AW: JSON iterieren, aber wie?
Wie lese ich denn das aus?
"length": [ 0, "mm" ]. Sowas verstehe ich: "important_information": { "hazard_warnings": null } subobj_important_information := (subobj as TJSONObject).Values['important_information'] as TJSONObject; Memo1.Lines.Add(subobj_important_information.Value s['hazard_warnings'].Value); |
AW: JSON iterieren, aber wie?
Die [] ist ein
![]() und {} ein TJSONObject. Über .P['abc'] kann man aber auch einen ganzen Pfad angeben (ähnlich dem ![]() Ich weiß, die Hilfe ![]() ![]() aber hier mal was aus den Sourcen. ![]()
Code:
/// <summary> Parses a JSON path with names and indexes.</summary>
/// <remarks> /// The syntax to write paths is similar to XPath but in a Json way. /// The following XPath expression: /// /entities/urls[0]/indices[1] /// would look like /// entities.urls[0].indices[1] (dot notation) /// or /// entities["urls"][0]["indices"][1] (bracket notation) /// /// The dot (.) token is used to access the object elements: /// ex: object.key /// /// The bracket ([]) token is used to access array or object elements: /// In array: cities[0] /// In object: city["name"] or city['name'] /// In object: ["city"]["name"] or ['city']['name'] /// /// The quote (" or ') is used to introduce a literal when the element is being written in bracket notation: /// ex:["first"]["second"] or ['first']['second'] /// /// To escape the quote in a literal use backslash (\): \" /// ex: ["quotes(\").should.be.escaped"] or ['quotes(\').should.be.escaped'] /// /// Note: The backslash will only escape quotes within a literal. Bracket notation can be useful when /// names can not be written in dot notation, like the objects keys with dot characters: /// ex: object["key.with.dots"] or object['key.with.dots'] /// /// </remarks> TJSONPathParser = record |
AW: JSON iterieren, aber wie?
So gehts:
Delphi-Quellcode:
// subobj: TJSONObject;
subobj_dimensions := subobj.Values['dimensions'] as TJSONObject; var subobj_length := subobj_dimensions.Values['length'] as TJSONArray; Memo1.Lines.Add('length = ' + subobj_length.Items[0].Value + ' ' + subobj_length.Items[1].Value); var subobj_width := subobj_dimensions.Values['width'] as TJSONArray; Memo1.Lines.Add('width = ' + subobj_width.Items[0].Value + ' ' + subobj_width.Items[1].Value); var subobj_height := subobj_dimensions.Values['height'] as TJSONArray; Memo1.Lines.Add('height = ' + subobj_height.Items[0].Value + ' ' + subobj_height.Items[1].Value); |
AW: JSON iterieren, aber wie?
Zitat:
Mit Variant?
Delphi-Quellcode:
Das fände ich jetzt aber auch nicht so geil.
type TWhatever_DimVals = Array of Variant;
type TWhatever_Dimensions : class private FLength : TWhatever_DimVals; FWidth : TWhatever_DimVals; FHeight : TWhatever_DimVals; public .... end; LG Incocnito |
AW: JSON iterieren, aber wie?
Zitat:
Der Zugriff auf einzelne Werte erfolgt so:
Delphi-Quellcode:
Die JSON Daten als Record abbilden, gelingt so:
uses
mormot.core.base, mormot.core.text, mormot.core.variants; var doc: TDocVariantData; item: PDocVariantData; itemDim: PDocVariantData; begin doc.InitJsonFromFile('data.json', JSON_[mFastFloat]); for item in doc.A['data'].Objects do begin itemDim := item.O['article'].O['dimensions']; with itemDim.A['length']^ do ShowMessage(Utf8ToString(FormatUtf8('Length: %%', [Value[0], Value[1]]))); end;
Delphi-Quellcode:
Die Record Definition muss die JSON Werte nicht vollständig abbilden, wenn zum Einlesen der Mode Tolerant gewählt wird.
uses
mormot.core.base, mormot.core.json, mormot.core.text, mormot.core.os; type TDataRec = record data: array of record article: record id: Integer; dimensions: record length: array of Variant; width: array of Variant; height: array of Variant; end; end; end; meta: record pagination: record total: Integer; count: Integer; end; end; end; var i: Integer; rec: TDataRec; json: RawJson; begin json := StringFromFile('data.json'); if RecordLoadJson(rec, json, TypeInfo(TDataRec)) then begin for i := 0 to High(rec.data) do begin with rec.data[i].article.dimensions do ShowMessage(Utf8ToString(FormatUtf8('Length: %%', [length[0], length[1]]))); end; end; Bis bald... Thomas |
AW: JSON iterieren, aber wie?
mach doch einfach ne Klasse von dem Json dann kannst du einfach aus der Klasse die Informationen auslesen.
![]() Der Aufruf
Delphi-Quellcode:
Die Klasse
uses RootUnit;
procedure UseJson(pJson:string); var Root: TRoot; Data: TData; begin Root := TRoot.Create; try Root.AsJson := pJson; // in Root.Data sind alle Items aus dem Array drin for Data in Root.Data do begin Data.Article.... end; finally Root.Free; end; end;
Delphi-Quellcode:
unit RootUnit;
interface uses Pkg.Json.DTO, System.Generics.Collections, REST.Json.Types; {$M+} type TArticle = class; TDimensions = class; TImportantInformation = class; TLinks = class; TPagination = class; TUnit = class; TLinks = class end; TPagination = class private FCount: Integer; [JSONName('current_page')] FCurrentPage: Integer; FLinks: TLinks; [JSONName('per_page')] FPerPage: Integer; FTotal: Integer; [JSONName('total_pages')] FTotalPages: Integer; published property Count: Integer read FCount write FCount; property CurrentPage: Integer read FCurrentPage write FCurrentPage; property Links: TLinks read FLinks; property PerPage: Integer read FPerPage write FPerPage; property Total: Integer read FTotal write FTotal; property TotalPages: Integer read FTotalPages write FTotalPages; public constructor Create; destructor Destroy; override; end; TMeta = class private FPagination: TPagination; published property Pagination: TPagination read FPagination; public constructor Create; destructor Destroy; override; end; TImportantInformation = class end; TDimensions = class(TJsonDTO) private [JSONName('height')] FHeightArray: TArray<Integer>; [JSONMarshalled(False)] FHeight: TList<Integer>; [JSONName('length')] FLengthArray: TArray<Integer>; [JSONMarshalled(False)] FLength: TList<Integer>; [JSONName('width')] FWidthArray: TArray<Integer>; [JSONMarshalled(False)] FWidth: TList<Integer>; function GetHeight: TList<Integer>; function GetLength: TList<Integer>; function GetWidth: TList<Integer>; protected function GetAsJson: string; override; published property Height: TList<Integer> read GetHeight; property Length: TList<Integer> read GetLength; property Width: TList<Integer> read GetWidth; public destructor Destroy; override; end; TUnit = class private FAmount: Double; FUnit: string; published property Amount: Double read FAmount write FAmount; property &Unit: string read FUnit write FUnit; end; TArticle = class private [JSONName('created_at')] FCreatedAt: string; FDimensions: TDimensions; FId: Integer; [JSONName('important_information')] FImportantInformation: TImportantInformation; FManufacturer: string; FName: string; FPrice: Double; FQuality: string; FSku: string; FStock: Integer; FUnit: TUnit; FWeight: Double; published property CreatedAt: string read FCreatedAt write FCreatedAt; property Dimensions: TDimensions read FDimensions; property Id: Integer read FId write FId; property ImportantInformation: TImportantInformation read FImportantInformation; property Manufacturer: string read FManufacturer write FManufacturer; property Name: string read FName write FName; property Price: Double read FPrice write FPrice; property Quality: string read FQuality write FQuality; property Sku: string read FSku write FSku; property Stock: Integer read FStock write FStock; property &Unit: TUnit read FUnit; property Weight: Double read FWeight write FWeight; public constructor Create; destructor Destroy; override; end; TData = class private FArticle: TArticle; published property Article: TArticle read FArticle; public constructor Create; destructor Destroy; override; end; TRoot = class(TJsonDTO) private [JSONName('data'), JSONMarshalled(False)] FDataArray: TArray<TData>; [GenericListReflect] FData: TObjectList<TData>; FMeta: TMeta; function GetData: TObjectList<TData>; protected function GetAsJson: string; override; published property Data: TObjectList<TData> read GetData; property Meta: TMeta read FMeta; public constructor Create; override; destructor Destroy; override; end; implementation { TPagination } constructor TPagination.Create; begin inherited; FLinks := TLinks.Create; end; destructor TPagination.Destroy; begin FLinks.Free; inherited; end; { TMeta } constructor TMeta.Create; begin inherited; FPagination := TPagination.Create; end; destructor TMeta.Destroy; begin FPagination.Free; inherited; end; { TDimensions } destructor TDimensions.Destroy; begin GetHeight.Free; GetLength.Free; GetWidth.Free; inherited; end; function TDimensions.GetHeight: TList<Integer>; begin Result := List<Integer>(FHeight, FHeightArray); end; function TDimensions.GetLength: TList<Integer>; begin Result := List<Integer>(FLength, FLengthArray); end; function TDimensions.GetWidth: TList<Integer>; begin Result := List<Integer>(FWidth, FWidthArray); end; function TDimensions.GetAsJson: string; begin RefreshArray<Integer>(FHeight, FHeightArray); RefreshArray<Integer>(FLength, FLengthArray); RefreshArray<Integer>(FWidth, FWidthArray); Result := inherited; end; { TArticle } constructor TArticle.Create; begin inherited; FUnit := TUnit.Create; FDimensions := TDimensions.Create; FImportantInformation := TImportantInformation.Create; end; destructor TArticle.Destroy; begin FUnit.Free; FDimensions.Free; FImportantInformation.Free; inherited; end; { TData } constructor TData.Create; begin inherited; FArticle := TArticle.Create; end; destructor TData.Destroy; begin FArticle.Free; inherited; end; { TRoot } constructor TRoot.Create; begin inherited; FMeta := TMeta.Create; end; destructor TRoot.Destroy; begin FMeta.Free; GetData.Free; inherited; end; function TRoot.GetData: TObjectList<TData>; begin Result := ObjectList<TData>(FData, FDataArray); end; function TRoot.GetAsJson: string; begin RefreshArray<TData>(FData, FDataArray); Result := inherited; end; end. |
AW: JSON iterieren, aber wie?
Zitat:
also kein
Delphi-Quellcode:
sondern jeweils Wert und Einheit ala
"length": [ 0, 1, 2 ],
Delphi-Quellcode:
statt als Array wäre es wohl in zwei Feldern angebrachter
"length": [ 0, "mm" ],
Length: Integer; LengthUnit: string; // oder Enum oder ein nur Feld und beim Lesen in eine Grundeinheit umgerechnet |
AW: JSON iterieren, aber wie?
@himitsu war nur Copy and Paste von der Webseite... ich bin nicht über die Daten gegangen das könnte man natürlich als String einlesen
|
AW: JSON iterieren, aber wie?
Zitat:
Wer auch immer das Json designed hat. Wäre ja schon kein Problem in Delphi mehr, wenn es
Code:
statt
"length": { 0, "mm" },
Code:
wäre. ;-)
"length": [ 0, "mm" ],
LG Incocnito |
AW: JSON iterieren, aber wie?
Zitat:
Code:
Aber, wie du schon sagst
"length": { "value": 0, "unit": "mm" },
Zitat:
|
AW: JSON iterieren, aber wie?
Zitat:
Bis bald... Thomas |
AW: JSON iterieren, aber wie?
Nicht alles lässt sich immer (einfach) mit vorgefertigten Lösungen für JSON-zu-Objekt behandeln.
Manchmal muß man für gewisse Sonderfälle dann einfach selber Hand anlegen. * entweder ohne Objektmapping arbeiten * oder mit einem Transformation-Tool die JSON-Datei etwas umformatieren (Dinge verschieben/ändern/...) * oder diese paar Felder nicht automatisch behandeln lassen und sie anschließend manuell aus dem JSON ins Objekt übernehmen (das was geht automatisch und dann der Rest) |
AW: JSON iterieren, aber wie?
Zitat:
|
AW: JSON iterieren, aber wie?
Zitat:
![]() ![]() Bis bald... Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz