AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

JSON iterieren, aber wie?

Ein Thema von stifflersmom · begonnen am 24. Jun 2022 · letzter Beitrag vom 27. Sep 2022
Antwort Antwort
Seite 1 von 2  1 2      
stifflersmom

Registriert seit: 8. Dez 2005
Ort: 24994 Holt
379 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

JSON iterieren, aber wie?

  Alt 24. Jun 2022, 09:13
Moin,

ich stehe hier gerade ein wenig auf dem Schlauch und bräuchte mal eine Hilfestellung.

Gegeben ist folgendes JSON:
Code:
{
    "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": {}
        }
    }
}
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.

Gruß
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.624 Beiträge
 
Delphi 12 Athens
 
#2

AW: JSON iterieren, aber wie?

  Alt 24. Jun 2022, 09:28
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;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Maliko

Registriert seit: 20. Jun 2019
91 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: JSON iterieren, aber wie?

  Alt 24. Jun 2022, 09:35
Es gibt folgende Funktion:

TJson.JsonToObject<TClass>(sJsonString) 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. https://www.uweraabe.de/Blog/2020/03...ts-with-tjson/

Vielleicht kannst du damit mehr anfangen.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: JSON iterieren, aber wie?

  Alt 24. Jun 2022, 09:40
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:
  1. Du bildest die ganzen Dinge wie z.B. "article" als Delphi-Objekt ab und lässt dir den gesamten Kram als Delphi-Struktur deserialisieren
  2. Dich interessiert nur etwas wie z.B. "Gib mir einfach nur alle Artikelnamen" und holst dir mit dem Weg des geringsten Widerstandes auf direktem Wege ebendiese Daten

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.
  Mit Zitat antworten Zitat
stifflersmom

Registriert seit: 8. Dez 2005
Ort: 24994 Holt
379 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: JSON iterieren, aber wie?

  Alt 26. Jun 2022, 12:45
@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.
  Mit Zitat antworten Zitat
Pfaffe

Registriert seit: 29. Jan 2009
297 Beiträge
 
Delphi 12 Athens
 
#6

AW: JSON iterieren, aber wie?

  Alt 25. Sep 2022, 22:43
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);
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#7

AW: JSON iterieren, aber wie?

  Alt 26. Sep 2022, 00:12
Die [] ist ein Delphi-Referenz durchsuchenTJSONArray,
und {} ein TJSONObject.

Über .P['abc'] kann man aber auch einen ganzen Pfad angeben (ähnlich dem Bei Google suchenXPath von XML)
Ich weiß, die Hilfe Delphi-Referenz durchsuchenTJSONObject.P ist wieder mal unterirdisch,
https://docwiki.embarcadero.com/Libr...N.TJSONValue.P
aber hier mal was aus den Sourcen.

https://docwiki.embarcadero.com/Libr...er#Description
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
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (26. Sep 2022 um 00:16 Uhr)
  Mit Zitat antworten Zitat
Pfaffe

Registriert seit: 29. Jan 2009
297 Beiträge
 
Delphi 12 Athens
 
#8

AW: JSON iterieren, aber wie?

  Alt 26. Sep 2022, 08:26
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);
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
223 Beiträge
 
#9

AW: JSON iterieren, aber wie?

  Alt 26. Sep 2022, 09:49
Wie lese ich denn das aus?
"length": [
0,
"mm"
].
Sowas verstehe ich:
"important_information": {
"hazard_warnings": null
}...
Oha, das hatte ich gar nicht gesehen. Wenn man sowas als Klasse (für TJson.JsonToObject<TMyClass>(sValue)) abbilden will, wie soll das denn gehen?
Mit Variant?
Delphi-Quellcode:
type TWhatever_DimVals = Array of Variant;

type
  TWhatever_Dimensions : class
  private
    FLength : TWhatever_DimVals;
    FWidth : TWhatever_DimVals;
    FHeight : TWhatever_DimVals;
  public
    ....
  end;
Das fände ich jetzt aber auch nicht so geil.

LG Incocnito
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#10

AW: JSON iterieren, aber wie?

  Alt 26. Sep 2022, 22:41
Wie lese ich denn das aus?
"length": [
0,
"mm"
]
Mit Hilfe von mORMot lassen sich einzelne Wert auslesen, oder die gesamte Struktur als Objekt/Record abbilden.

Der Zugriff auf einzelne Werte erfolgt so:
Delphi-Quellcode:
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;
Die JSON Daten als Record abbilden, gelingt so:
Delphi-Quellcode:
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;
Die Record Definition muss die JSON Werte nicht vollständig abbilden, wenn zum Einlesen der Mode Tolerant gewählt wird.

Bis bald...
Thomas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz