hydrobyte / McJSON

A Delphi / Lazarus / C++Builder simple and small class for fast JSON parsing.
MIT License
58 stars 20 forks source link

New empty key destroys the json structure #17

Closed totyaxy closed 1 year ago

totyaxy commented 1 year ago

In practice, I also solve the configuration with MCJson. Therefore, due to new situations, unexpected errors also occur. If I add a key to an existing structure (asJson, LoadFromFile) (main key, without value, because it won't have any), it destroys the json, and next time it won't even be loaded. It's possible that an empty key (category) shouldn't be added this way, but I don't think it should spoil the json structure.

procedure TForm1.Button1Click(Sender: TObject);
const
  fn = 'test.json';
var
  N: TMcJsonItem;
begin
  DeleteFile(fn);

  N := TMcJsonItem.Create;
  try
    N.AsJSON := '{"i": 123, "f": 123.456, "s": "abc", "b": true, "n": null}';

    //N.SaveToFile(fn);
    //N.LoadFromFile(fn);
    //Memo1.Lines.LoadFromFile(fn);

    N.Add('EmptyNewKey'); // <- this destroy json structure

    N.SaveToFile(fn);
    N.LoadFromFile(fn);
    Memo1.Lines.LoadFromFile(fn);

  except
    N.Free;
  end;
end; 
hydrobyte commented 1 year ago

Hi!

Yeap, it need a fix. I'm working on it.

Meanwhile, try:

N.Add('EmptyNewKey')->AsString = '';
totyaxy commented 1 year ago

Thanks for the tip! :)

But the result is the key, with empty value:

  },
  "EmptyNewKey": ""
}

I'd like to use a subkey, like as "o" int this example:

N.AsJson:='{"o": {"k1":"v1", "k2":"v2"}}';
hydrobyte commented 1 year ago

But the result is the key, with empty value:

N.Add('EmptyNewKey')->AsString = '';

I think this works.

totyaxy commented 1 year ago

Works, but the result is different.

excepted: (o = EmptyNewKey)

{
    "o": {
        "k1": "v1",
        "k2": "v2"
    }
}

your example (invalid json):

{
    "o" = "" {
        "k1": "v1",
        "k2": "v2"
    }
}

Created with a subkey, it obviously works, and you also wrote that this is a bug that you are fixing, thank you!

hydrobyte commented 1 year ago

I think we are diverging.

Empty key is different from empty value.

I didn't get your sequence.

A different example

Here N.AsJson:='{"o": {"k1":"v1", "k2":"v2"}}'; works fine.

Where in this JSON string do you want a empty value?

Doubt

Created with a subkey

How? Please, always make your example as clear as possible.

Again, different examples.

and you also wrote that this is a bug that you are fixing

The bug is as you shown and I agreed: N.Add('EmptyNewKey');

To sum up

With all my respect, let me say something: I think you didn't get how a little piece of code published into Github with MIT license works. If you see something wrong, this is not a Helpdesk platform, OK? Try to collaborate, mainly spending some time with a good error description. For example, your first post is what I expect. The second and third ones are confusing/misleading.

totyaxy commented 1 year ago

As I wrote, I use a translator to write text. You have written a very good library, and I think it will only improve if I flag errors and make comments. Since I also write programs, I know this is not a help desk, but as I wrote, your library will get better and better. If you fix a mistake after 5 years, I can't even say a word :)

I try to be as precise as possible, but it mainly depends on the translator, who I think does a good job anyway. Thank you for your patience!

hydrobyte commented 1 year ago

English isn't a problem. I was talking about the code examples. My suggestion is to keep them clear as water and the issues more atomic.

Best.

totyaxy commented 1 year ago

Thank you, json isn't damaged now, but the result is not perfect, because I got this:

"Options": "",

Mean: Key with value (as you suggested earlier).

But I obviously only wanted to add a key alone (parent key), since if I gave it together with a value, there would have been no problem. So I wanted from it:

JsonConfig.Add(cOptions);

to get this result in json (new parent key):

"Options": or "Options": {}

But in the end there is no problem, because if I add it together with a subkey and its value, I get the correct result. :

    JsonTmp := JsonConfig.Add(cOptions);
    JsonTmp.Add(cAutoBackup).AsBoolean := FAutoBackup;
"Options": {
    "AutoBackup": true
}

I tried to be as precise as possible. Thank you!

hydrobyte commented 1 year ago

Hi!

With good examples like these, it is simpler to follow you along.

Important: "Options": and {"Options":} are invalid JSON objects.

If you want a object with empty value, different from the default jvtString, try this:

JsonConfig.Add(cOptions).ItemType := jitObject; 
// or
JsonConfig.Add(cOptions, jitObject);

It will generate:

{
  "Options": {}
}

I've included a test about this into Test05() (next commit).

Best.

totyaxy commented 1 year ago

"jitObject" is the key, thank you!