Recent

Author Topic: How to rename or move a subkey using TJSONConfig  (Read 369 times)

anse

  • New Member
  • *
  • Posts: 10
How to rename or move a subkey using TJSONConfig
« on: March 17, 2025, 12:49:14 pm »
I found that TJSONConfig object today and it was love at first sight. I can easily manage my own application's configuration, even with some old quirks I still want to keep a while for compatibility reasons.
However, is there a way to move or rename a JSON subkey somehow? Let's say I have such a structure:

Code: Javascript  [Select][+][-]
  1. {
  2.   "a": 1,
  3.   "folder": {
  4.     "b": 2,
  5.     "subfolder": {
  6.       "c": 3
  7.     }
  8.   }
  9. }
  10.  

I would want to rename "folder" to "folder2". There is no built-in method for that in the TJSONConfig object. I guess I should
  • .OpenKey('/folder')
  • copy its content (how?)
  • .OpenKey('folder2', True)
  • assign the old contents?
  • .DeleteKey('folder')

Code: Pascal  [Select][+][-]
  1. uses
  2.   jsonConf;
  3.  
  4. var
  5.   JsonFilePath: String;
  6. begin
  7.   JsonFilePath := IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName)) + 'settings.json';
  8.   FJsConf := TJSONConfig.Create(nil);
  9.   FJsConf.Formatted := True;
  10.   FJsConf.Filename := JsonFilePath;
  11.   FJsConf.OpenKey('/folder');
  12.   // rename to "folder2"
  13. end;
  14.  
« Last Edit: March 17, 2025, 01:52:49 pm by anse »

anse

  • New Member
  • *
  • Posts: 10
Re: How to rename or move a subkey using TJSONConfig
« Reply #1 on: March 19, 2025, 09:47:14 am »
I found I need to manipulate the internal json objects, so I derived my own TJSONConfigExtended from TJSONConfig and implemented a .MoveKey procedure:

Code: Pascal  [Select][+][-]
  1. type
  2.   TJSONConfigExtended = class(TJSONConfig)
  3.     public
  4.       function AddEndSlash(Path: UnicodeString): UnicodeString;
  5.       function StripEndSlash(Path: UnicodeString): UnicodeString;
  6.       procedure MoveKey(SourcePath: UnicodeString; TargetPath: UnicodeString);
  7.   end;
  8.  
  9.  
  10. implementation
  11.  
  12. { TJSONConfigExtended }
  13.  
  14. function TJSONConfigExtended.AddEndSlash(Path: UnicodeString): UnicodeString;
  15. begin
  16.   Result := Path;
  17.   if Result[Length(Result)] <> '/' then
  18.     Result := Result + '/';
  19. end;
  20.  
  21. function TJSONConfigExtended.StripEndSlash(Path: UnicodeString): UnicodeString;
  22. begin
  23.   Result := Path;
  24.   if Result[Length(Result)] = '/' then
  25.     Delete(Result, Length(Result), 1);
  26. end;
  27.  
  28. procedure TJSONConfigExtended.MoveKey(SourcePath: UnicodeString;
  29.   TargetPath: UnicodeString);
  30. var
  31.   OldNode, NewNode, NewNodeParent: TJSONObject;
  32.   NewNodeName: UnicodeString;
  33.   TargetPathSlash, TargetPathNoSlash: UnicodeString;
  34. begin
  35.  
  36.   if Length(SourcePath) = 0 then
  37.     Raise EJSONConfigError.Create('Cannot move from empty path');
  38.   if Length(TargetPath) = 0 then
  39.     Raise EJSONConfigError.Create('Cannot move to empty path');
  40.  
  41.   SourcePath := AddEndSlash(SourcePath);
  42.   OldNode := FindObject(SourcePath, False);
  43.   if not Assigned(OldNode) then
  44.     raise EJSONConfigError.CreateFmt('Source path does not exist: %s', [SourcePath]);
  45.  
  46.   TargetPathSlash := AddEndSlash(TargetPath);
  47.   TargetPathNoSlash := StripEndSlash(TargetPath);
  48.  
  49.   // Error if target exists
  50.   NewNode := FindObject(TargetPathSlash, False);
  51.   if Assigned(NewNode) then
  52.     Raise EJSONConfigError.CreateFmt('Target path already exists: %s', [TargetPathSlash]);
  53.  
  54.   // Create copied key
  55.   NewNodeParent := FindObject(TargetPathNoSlash, True, NewNodeName);
  56.   NewNodeParent.Add(NewNodeName, OldNode.Clone);
  57.  
  58.   // Deleting source key. Note we have cloned this before.
  59.   DeletePath(SourcePath);
  60.   FModified:=True;
  61. end;
  62.  
  63.  


 

TinyPortal © 2005-2018