0

Is there a convenient way of identifying the parent (not owner) object of a TJSONObject? The only way I've found so far was to parse the key into its elements and then extract it with string manipulation. Surely there is a better way?

I'm using C++ Builder 10.4 but I'm sure someone who knows the System.JSON Delphi library will be able to help too.

So, as an example I want to change "foobar.name" from "Spastika" to "Deon" in the TJSONObject parsed from something like this:

{
   "foo": "bar",
   "foobar": {
      "name": "Spastika"
   }
}

System.JSON doesn't offer a method to simply change the value of foobar.name.
(It's hard to believe but its true - if I'm wrong, stop me there and tell me how, please, please, please )

So, let's say I've got a TJSONOBject called docJSON that parsed the JSON above.

  1. When I call docJSON->RemovePair("foobar.name") the pair is removed as expected.
  2. HOWEVER:
    When I call docJSON->AddPair("foobar.name", "Deon") the pair isn't added under the foobar object, but in stead as a foobar.name string in the root of docJSON and the result is this:
    {
       "foo": "bar",
       "foobar.name": "Deon",
       "foobar": {}
    }
    

So, that is why I need to identify the parent of "foobar.name" "conveniently" to be able to lateron add the "name" pair to it after removing it.

All just to change a value in a JSON object - quite painful.

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
Spastika
  • 364
  • 3
  • 10
  • How did you manage to determine the parent by just parsing one of an object's keys? And why didn't you include your code into your question? Up to what is "_convenient_" to you? – AmigoJack Mar 16 '22 at 14:39
  • Unlike the XML framework, the JSON framework simply does not store or expose references to parent objects. Why do you need this? – Remy Lebeau Mar 16 '22 at 14:54
  • With TJSONObjects the only way to change pairs is by removing the whole pair and then adding a new pair with the same key (no way to just change the value). It's easy to remove the pair with `RemovePair` which takes an APath, but when using `AddPair`, the key argument is not an APath. I was wondering about sample code, but it would have been too much. These questions help to go right to the core --- I'll add some code now. – Spastika Mar 17 '22 at 07:18

1 Answers1

1

One thing to understand in JSON is: everything is either an object or an array:

  • Objects have properties, to which you can assign values - this is how name=value pairs can be done. They start and end with curly brackets: { }.
  • Arrays are lists of values only. They start and end with square brackets: [ ].

Now let's turn your JSON example into something that outlines this even more - you have one large object with 2 properties. The 2nd property has as value another object with only 1 property:

{
   "this_objects_1st_property": "text",
   "this_objects_2nd_property": {
      "new_objects_1st_property": "text again"
   }
}

What should happen if you want to assign a different value to this_objects_2nd_property? It should not be an object anymore, but instead text, too (e.g. "other text"), or a number (e.g. 1337). Or an array. You want to replace a text value with another text value, but that's just by conincidence the same data type - you could also replace a text value with another object as value.

You don't want to AddPair() to the whole document - you want to access the object that lies under the property "foobar" to then access that's property named "name". Operate on the inner object and do RemovePair( "name" ) on that, to then AddPair( "name", "Deon" ).

See the following existing Q&As:

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
  • I'm 100% with you, but there is no convenient way to get hold of the parent object of an existing pair so that the "inner object" can be replaced. My question is more about accessing the parent for the reasons you provide in a better way than parsing the path of the inner object and determining the parent from that. It feels like ***System.JSON*** and all its classes should provide a convenient way of doing that. – Spastika Mar 18 '22 at 05:54
  • Creating such a function youself shouldn't be difficult: accept a path as parameter, then per path component (speak: "folder") get an object, then operate on that to get the next "folder" - and so on. – AmigoJack Mar 18 '22 at 10:49
  • I agree --- that's what I've done. I was just worried that I'm rolling custom infrastructure around ***System.JSON*** that really feels like it should already offer similar solutions. I keep getting disappointed by ***System.JSON***. – Spastika Mar 18 '22 at 13:43