How to back up multiple levels using TJSONIterator in Delphi?

I am trying to use TJSONIteratorin Delphi 10.2.2. Short question: "How do I go up two levels in Iterator?"

The following code illustrates my problem:

JsonRec := '{"v1":"Main","v2":"1.1","v3":{"id":"X45","mod":1.5,"r2":{"rv1":"99190","rv2":"TX"}},"v4":"ok","v5":69}';

PDS.Open;
PDS.Append;
StringReader := TStringReader.Create(JsonRec);
JsonTextReader := TJsonTextReader.Create(StringReader);
Iterator := TJSONIterator.Create(JsonTextReader);
If Iterator.Next('v1') Then
   PDS['Type'] := Iterator.AsString;
If Iterator.Next('v2') Then
   PDS['Version'] := Iterator.AsString;
If Iterator.Next('v3') Then
   Begin
   Iterator.Recurse;
   If Iterator.Next('id') Then
      PDS['BlackListInfo'] := Iterator.AsString;
   If Iterator.Next('mod') Then
      PDS['Speed'] := Iterator.AsDouble;
   If Iterator.Next('r2') Then
      begin
      Iterator.Recurse;
      if Iterator.Next('rv1') then
         PDS['Serial'] := Iterator.AsString;
      if Iterator.Next('rv2') then
         PDS['Location'] := Iterator.AsString;
      Iterator.Return;
      end;
   Iterator.Return;   //Second Return does not go up a level.
   if Iterator.Next('v4') then // Always fails
      PDS['CRC'] := Iterator.AsString;
   if Iterator.Next('v5') then
      PDS['ReportID'] := Iterator.AsInteger;
   PDS.Post;
   End;

Obviously, I am parsing the JSON string to put the data in the database ( PDS). When I issue the second return, I do not come to the expected level, and then I can not find v4. I suspect that I may need to use the method Rewind, but so far I have not been able to find the documentation.

Any help is greatly appreciated.

+4
source share
3 answers

, , , TJsonReader, json- ( ), delphi. ( : https://svn.code.sf.net/p/alcinoe/code/demos/ALJsonDoc/win32/AljsonDocDemo.exe)

Alcinoe (https://github.com/Zeus64/alcinoe) ( json- ​​ )

MyJsonDoc := TalJsonDocumentU.create;
try
  MyJsonDoc.loadFromJsonString('{"v1":"Main","v2":"1.1","v3":{"id":"X45","mod":1.5,"r2":{"rv1":"99190","rv2":"TX"}},"v4":"ok","v5":69}');
  PDS['Type'] := MyJsonDoc.node.getchildNodeValueText('v1', ''{default});
  PDS['Version'] := MyJsonDoc.node.getchildNodeValueText('v2', ''{default});
  PDS['BlackListInfo'] := MyJsonDoc.node.getchildNodeValueText(['v3', 'id'], ''{default});
  PDS['Speed'] := MyJsonDoc.node.getchildNodeValueFloat(['v3', 'mod'], 0{default});
  PDS['Serial'] := MyJsonDoc.node.getchildNodeValueText(['v3', 'r2', 'rv1'], ''{default});
  PDS['Location'] := MyJsonDoc.node.getchildNodeValueText(['v3', 'r2', 'rv2'], ''{default});
  PDS['CRC'] := MyJsonDoc.node.getchildNodeValueText('v4', ''{default});
  PDS['ReportID'] := MyJsonDoc.node.getchildNodeValueInt32('v5', 0{default});
finally
  MyJsonDoc.free;
end;
+1

Iterator.Next Iterator.Return. , - .

  if Iterator.Next('rv2') then
     PDS['Location'] := Iterator.AsString;
  Iterator.Return;
  end;

  if Iterator.Next('rv2') then
     PDS['Location'] := Iterator.AsString;
  Iterator.Return;
  Iterator.Next;
  end;

, , , , Return . impelemntation, , Return , , .

Return r2 , , , not FReader.IsEndToken (FReader.TokenType) .

Iterator.Next('v4') v3 1, FFinished True, , Next , - if FFinished then Exit. reset FFinish - Return Rewind.

+1

, TJSONIterator . - , :

...
  ecDebug: TMemo;
...
uses
  System.JSON.Builders,
  System.JSON.Readers,
...
procedure TForm1.Button1Click(Sender: TObject);
const
  JsonRec = '{"v1":"Main","v2":"1.1","v3":{"id":"X45","mod":1.5,' +
    '"r2":{"rv1":"99190","rv2":"TX"}},"v4":"ok","v5":69}';
var
  StringReader: TStringReader;
  JsonTextReader: TJsonTextReader;
  Iterator: TJSONIterator;
begin
  JsonTextReader:= nil;
  Iterator:= nil;
  StringReader:= TStringReader.Create(JsonRec);
  try
    JsonTextReader:= TJsonTextReader.Create(StringReader);
    Iterator:= TJSONIterator.Create(JsonTextReader);
    while Iterator.Next do
    begin
      if Iterator.Key = 'v1' then
        ecDebug.Lines.Add(Format('Type = %s', [Iterator.AsString]))
      else if Iterator.Key = 'v2' then
        ecDebug.Lines.Add(Format('Version = %s', [Iterator.AsString]))
      else if Iterator.Key = 'v3' then
      begin
        Iterator.Recurse;
        while Iterator.Next do
        begin
           if Iterator.Key = 'id' then
             ecDebug.Lines.Add(Format('BlackListInfo = %s', [Iterator.AsString]))
           else if Iterator.Key = 'mod' then
             ecDebug.Lines.Add(Format('Speed = %g', [Iterator.AsDouble]))
           else if Iterator.Key = 'r2' then
           begin
             Iterator.Recurse;
             while Iterator.Next do
             begin
               if Iterator.Key = 'rv1' then
                 ecDebug.Lines.Add(Format('Serial = %s', [Iterator.AsString])) 
               else if Iterator.Key = 'rv2' then
                 ecDebug.Lines.Add(Format('Location = %s', [Iterator.AsString]));
             end;
             Iterator.Return;
           end;
        end;
        Iterator.Return;
      end
      else if Iterator.Key = 'v4' then
        ecDebug.Lines.Add(Format('CRC = %s', [Iterator.AsString]))
      else if Iterator.Key = 'v5' then
        ecDebug.Lines.Add(Format('ReportID = %d', [Iterator.AsInteger]));
    end;
  finally
    Iterator.Free;
    JsonTextReader.Free;
    StringReader.Free;
  end;
end;

I believe that this is how it is TJSONIteratorintended for use. This code is independent of the order of the JSON elements.

Conclusion in the memo:

Type = Main
Version = 1.1
BlackListInfo = X45
Speed = 1,5
Serial = 99190
Location = TX
CRC = ok
ReportID = 69
0
source

Source: https://habr.com/ru/post/1695261/


All Articles