Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   TJsonValue mit Punkt im ValueNamen (https://www.delphipraxis.net/208658-tjsonvalue-mit-punkt-im-valuenamen.html)

gmc616 2. Sep 2021 11:20

TJsonValue mit Punkt im ValueNamen
 
Hallo Delphi-Praxis,

ich beschäftige mich zZ mit MS-Graph um aus der Office365-Cloud per REST-API Version 1.0 (https://docs.microsoft.com/de-de/gra...-1.0&tabs=http)
u.a. eMail abholen zu können.

Als Result bekommt man einen JSON-String, welche ich mit den Delphi-Board-Mitteln TJSONObject auslese/parse.
Funktioniert soweit ganz gut.

Da ich ein "vorsichtiger" Programmierer bin, prüfen ich vor dem Lesen der Values mit TJSONObject.FindValue auf das vorhanden sein des ValueNames, bevor ich ihn mit TJSONValue.GetValue schießlich lese.
Ansonsten wirft die Anwendung eine Exception C0000005, sollte der ValueName nicht existieren.

Nun sind aber in diesem MS-Graph-JsonString Values enthalten, an die ich gern heran kommten möchte, welche aber einen Punkt im ValueNamen haben z.B. "@odata.etag".
Laut Delphi-Doku (https://docwiki.embarcadero.com/Libr...alue.FindValue) ist das aber nicht möglich.

Ein direkter Zugriff auf diese Value mit TJSONObject.GetValue funktioniert aber, zumindest wenn das Value tatsächlich existiert. Wenn nicht -> Exception C0000005

Also, FindValue funktioniert hier nicht.
TryGetValue basiert vermutlich ebenfalls auf FindValue und gibt FALSE zurück, auch wenn der ValueName "@odata.etag" existiert.

Nun kann ich ich den Zugriff per try .. execpt zwar kappselt, was dann in der Anwendung funktionieren würde, aber in der IDE wirft der Debugger immer wieder die Exception C0000005, was nervig ist.
Gerade diese Exception C0000005 in der IDE als Ausnahme hinzu zu fügen, ist sicherlich nicht die beste Idee.

Kann ich diese Exception C0000005 im Code/IDE irgendwie unterdrücken? Mit einem Compilier-Schalter eventuell?
Oder kennt jemand eine andere Möglichkeit, diese Exception C0000005 zu umgehen, wenn ich TJSONObject.GetValue('@odata.etag') aufrufen möchte und dieses Value nicht existiert?

Danke.

Der schöne Günther 2. Sep 2021 12:25

AW: TJsonValue mit Punkt im ValueNamen
 
Bringt dich das hier weiter?

https://www.delphipraxis.net/201484-...-im-namen.html

gmc616 2. Sep 2021 12:50

AW: TJsonValue mit Punkt im ValueNamen
 
Leider nicht. Der Thread trifft genau mein Problem. Und so weit wie dort, bin ich ja auch schon.

Der Problem ist aber, das
Delphi-Quellcode:
jsonValue := jsonObject.GetValue('some.value'); // Findet er
knallt, sollte 'some.value' im JSON-String nicht existieren.
Und genau das möchte ich abfangen.

Hab grad gesehen, das FindValue als Parameter "const APath:string" besitzt, also kommen hier die Generics zu Zuge (nach deiner Aussage), die mit Punkten nicht umgehen kann/will.

Wenn doch aber Punkte nicht im JSON gestattet sind, wieso nutzt die dann M$? :pale:
Vielleicht brauche ich die "@"-Values mit Punkten ja auch garnicht, so das ich die ignorieren kann (nimm was du kriegen kannst :zwinker: ) ... so tief steckt ich im M$-Graph noch nicht drin :stupid:

Der schöne Günther 2. Sep 2021 13:10

AW: TJsonValue mit Punkt im ValueNamen
 
Was heißt für dich "knallen"?
GetValue() liefert
Delphi-Quellcode:
nil
, wenn es nichts hat. Das muss man prüfen, und kann nicht direkt sagen
Delphi-Quellcode:
myJsonObject.GetValue('some.value').ToString()
.

Hier ein Beispiel, das liefert folgendes, ohne jegliche Abstürze:

Code:
not found
Found: "Zwei"
not found
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses System.JSON;

procedure printValue(const input: String);
var
   asJsonObject: TJsonObject;
   someValue: TJsonValue;
begin
   asJsonObject := TJsonObject.ParseJSONValue(input) as TJsonObject;
   try
      someValue := asJsonObject.GetValue('some.value');
      if(Assigned(someValue)) then
         WriteLn('Found: ', someValue.ToString())
      else
         WriteLn('not found');
   finally
      asJsonObject.Destroy();
   end;
end;

procedure p();
const
   input1 = '{"some": {"value": "Eins"}}';
   input2 = '{"some.value": "Zwei"}';
   input3 = '{"some": {}}';
begin
   printValue(input1);
   printValue(input2);
   printValue(input3);
end;

begin
   p();
   ReadLn;
end.

Bbommel 2. Sep 2021 13:16

AW: TJsonValue mit Punkt im ValueNamen
 
Und hier noch etwas von den Kollegen von Stackoverflow: https://stackoverflow.com/questions/...json-in-delphi

Läuft letztlich wohl darauf hinaus, dass, wenn du die Generics-Methoden oder FindValue nutzen willst, mit
Code:
'["@odata.etag"]'
statt
Code:
'@odata.etag'
arbeiten musst.

Edit:
Noch aus der Delphi-Doku dazu:
Zitat:

Supported JSON Path Syntax

TJSONPathParser implements a subset of the JSON path specification defined by Stefan Göessner. Specifically, supported elements are:

Child operators for objects:
Use . to access object properties that do not contain a dot in their name. For example, use root.child to access the child property of the root object.
Use [] to access object properties that do contain a quoting character in their name. For example, use root['child.name'] or root["child.name"] to access the child.name property of the root object.

gmc616 2. Sep 2021 14:24

AW: TJsonValue mit Punkt im ValueNamen
 
Au man! :wall:

Klar. Wenn man
Delphi-Quellcode:
someValue := asJsonObject.GetValue('some.value').ToString;
ruft, ohne dass das Value existiert, knallts. Muß es ja!
Mit "Knallen" meine ich die Exception C0000005.
Manchmal steht man echt auf dem Schlauch. :oops:

Danke Günther!

Aber der Tipp von Bbommel ist sogar noch besser. :thumb: Hatte die Delphi-Doku wohl falsch verstanden.
Das macht vieles einfacher.

Danke Bbommel!


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:33 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