PKGeorgiev / Delphi-JsonToDelphiClass

Generates Delphi Classes based on JSON string (Json To Delphi Class Generator / JSON Data Binding Tool)
MIT License
236 stars 122 forks source link

Ampersand for "label" #10

Open HemulGM opened 4 years ago

HemulGM commented 4 years ago

I use the generator on the site.

When generating a field with the name "label", an ampersand is necessary like with the field "type".

JensBorrisholt commented 4 years ago

@HemulGM have a look at my branch https://github.com/JensBorrisholt/Delphi-JsonToDelphiClass

I've fixed that there.

Regards

Jens Borrisholt

JACAmetekDenmark commented 10 months ago

New with JSON and Delphi, piece of cake with VS C# , however this is becoming a nightmare in delphi. The & causes a small "sET" in my generated file. Must be a "SET" to match the label when reading from .dot module. Is there a simple way around it. TJsonDTO is great to read an existing JSON file but a pain to generate. Is there a function to extract the contents into a TStringList so I can pretty-write to a file? Thanks in advance James

HemulGM commented 10 months ago

New with JSON and Delphi, piece of cake with VS C# , however this is becoming a nightmare in delphi. The & causes a small "sET" in my generated file. Must be a "SET" to match the label when reading from .dot module. Is there a simple way around it. TJsonDTO is great to read an existing JSON file but a pain to generate. Is there a function to extract the contents into a TStringList so I can pretty-write to a file? Thanks in advance James

JSON and its mechanics have nothing to do with it. This is a reserved word and there are exactly the same problems with them in C#.

JACAmetekDenmark commented 10 months ago

Thanks for the quick reply. Protocol and communications DLL (to the device) are developed in C# with no conflicts, it's only now a problem with reserved word clashes in Delphi, when integrating the host systems developed in Delphi. It never occurred to me it would be an issue with delphi. Thanks anyway.

HemulGM commented 10 months ago

Thanks for the quick reply. Protocol and communications DLL (to the device) are developed in C# with no conflicts, it's only now a problem with reserved word clashes in Delphi, when integrating the host systems developed in Delphi. It never occurred to me it would be an issue with delphi. Thanks anyway.

No one is stopping you from not using reserved words at all. Delphi serialization, like everywhere else, works with attributes, through which you can specify any field name from JSON for a field in a class.

HemulGM commented 10 months ago
  TCategoryScores = class
  private
    FHate: Extended;
    [JSONName('hate/threatening')]
    FHatethreatening: Extended;
    [JSONName('self-harm')]
    FSelfharm: Extended;
    FSexual: Extended;
    [JSONName('sexual/minors')]
    FSexualminors: Extended;
    FViolence: Extended;
    [JSONName('violence/graphic')]
    FViolencegraphic: Extended;
    FHarassment: Extended;
    [JSONName('harassment/threatening')]
    FHarassmentthreatening: Extended;
    [JSONName('self-harm/intent')]
    FSelfharmintent: Extended;
    [JSONName('self-harm/instructions')]
    FSelfharminstructions: Extended;
  public
    /// <summary>
    /// Content that expresses, incites, or promotes hate based on race, gender, ethnicity, religion, nationality,
    /// sexual orientation, disability status, or caste. Hateful content aimed at non-protected groups (e.g., chess players)
    /// is harrassment.
    /// </summary>
    property Hate: Extended read FHate write FHate;
    /// <summary>
    /// Hateful content that also includes violence or serious harm towards the targeted group based on race,
    /// gender, ethnicity, religion, nationality, sexual orientation, disability status, or caste.
    /// </summary>
    property HateOrThreatening: Extended read FHatethreatening write FHatethreatening;
    /// <summary>
    /// Content that expresses, incites, or promotes harassing language towards any target.
    /// </summary>
    property Harassment: Extended read FHarassment write FHarassment;
    /// <summary>
    /// Harassment content that also includes violence or serious harm towards any target.
    /// </summary>
    property HarassmentOrThreatening: Extended read FHarassmentthreatening write FHarassmentthreatening;
    /// <summary>
    /// Content that promotes, encourages, or depicts acts of self-harm, such as suicide, cutting, and eating disorders.
    /// </summary>
    property SelfHarm: Extended read FSelfharm write FSelfharm;
    /// <summary>
    /// Content where the speaker expresses that they are engaging or intend to engage in acts of self-harm,
    /// such as suicide, cutting, and eating disorders.
    /// </summary>
    property SelfHarmOrIntent: Extended read FSelfharmintent write FSelfharmintent;
    /// <summary>
    /// Content that encourages performing acts of self-harm, such as suicide, cutting, and eating disorders,
    /// or that gives instructions or advice on how to commit such acts.
    /// </summary>
    property SelfHarmOrInstructions: Extended read FSelfharminstructions write FSelfharminstructions;
    /// <summary>
    /// Content meant to arouse sexual excitement, such as the description of sexual activity,
    /// or that promotes sexual services (excluding sex education and wellness).
    /// </summary>
    property Sexual: Extended read FSexual write FSexual;
    /// <summary>
    /// Sexual content that includes an individual who is under 18 years old.
    /// </summary>
    property SexualOrMinors: Extended read FSexualminors write FSexualminors;
    /// <summary>
    /// Content that depicts death, violence, or physical injury.
    /// </summary>
    property Violence: Extended read FViolence write FViolence;
    /// <summary>
    /// Content that depicts death, violence, or physical injury in graphic detail.
    /// </summary>
    property ViolenceOrGraphic: Extended read FViolencegraphic write FViolencegraphic;
  end;
JensBorrisholt commented 10 months ago

Hi @JACAmetekDenmark

I'm not exactly sure what the issue are. Could you provide me with an example?

Just send it direct to GitHUB@Borrisholt.dk

JACAmetekDenmark commented 10 months ago

Hej Jens, our latest calibrator series communication is based on JSON. (new to me). The communication to this and older models are developed in C# (.NET) through a Hydra wrapper because our host programs are in Delphi(non protected). All works fine however one feature called workorders require very large amount of data, so I used xml files to be read by host. I wanted to do the same with JSON files. All was well while testing with host C# programs. Because the defined protocol contains reserved words ie. “SET”, “Unit” & “Value” the Jsontodelphi generator defines Them with ampersands “sET”, “unit” & “value” , the file cannot be parsed as the nodes don’t match.

{ "SET":"AddWorkOrder", "TestType":"Calibration", "WO_GUID":"", "ID":"copy Temp pt100", "CompanyName":"Ametek Denmark", : : }

I have several varying arrays in the JSON so also trying to get my head around the [GenericListReflect] TArray/TObjectList representation.

It just seems very complicated in Delphi. Have enclosed a file generated by the .Net server DLL.

Regards James

Fra: Jens Borrisholt @.> Sendt: Tuesday, 24 October 2023 07.44 Til: PKGeorgiev/Delphi-JsonToDelphiClass @.> Cc: James Campion @.>; Mention @.> Emne: Re: [PKGeorgiev/Delphi-JsonToDelphiClass] Ampersand for "label" (#10)

NOTICE This came from an external source. Use caution when replying, clicking links, or opening attachments.

Hi @JACAmetekDenmarkhttps://urldefense.com/v3/__https:/github.com/JACAmetekDenmark__;!!HKOSU0g!HFlrf_Ax-1j3DHCTaaNWkwkfNfKSo4XAlwTDRJU-FHTmlhzsTP6K7LX1r4jbtfIRpszrrHF327Mgo2wMsMYC0cM-Y5M$

I'm not exactly sure what the issue are. Could you provide me with an example?

Just send it direct to @.**@.>

— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https:/github.com/PKGeorgiev/Delphi-JsonToDelphiClass/issues/10*issuecomment-1776570226__;Iw!!HKOSU0g!HFlrf_Ax-1j3DHCTaaNWkwkfNfKSo4XAlwTDRJU-FHTmlhzsTP6K7LX1r4jbtfIRpszrrHF327Mgo2wMsMYCvu2shSQ$, or unsubscribehttps://urldefense.com/v3/__https:/github.com/notifications/unsubscribe-auth/AEOPJBDXVGWQEZATJP5WCWTYA5ISZAVCNFSM4KHDR6CKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZXGY2TOMBSGI3A__;!!HKOSU0g!HFlrf_Ax-1j3DHCTaaNWkwkfNfKSo4XAlwTDRJU-FHTmlhzsTP6K7LX1r4jbtfIRpszrrHF327Mgo2wMsMYCqCnh8hU$. You are receiving this because you were mentioned.Message ID: @.**@.>>

JACAmetekDenmark commented 10 months ago

thanks for the heads up on attributes Is there a help source I can refer to before spamming you with questions? Have 2 which is the correct method to set a value? AddWorkOrder.AsJson:= '{ "SET":"AddWorkOrder" } '; &SET:='AddWorkOrder'; Best method to write to a file. TFile.WriteAllText('C:\Ametek\RTCRefresh\DelphiAddworker.JSON',AddWorkOrder.AsJson, TEncoding.UTF8); or Empty to TStringList then write to file? Apologies for the beginner questions. regards James

HemulGM commented 10 months ago

https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.JSON.Serializers.JsonNameAttribute

{
   "SET":"AddWorkOrder",
   "TestType":"Calibration",
   "WO_GUID":"",
   "ID":"copy Temp pt100",
   "CompanyName":"Ametek Denmark"
}
TAddWorkOrder = class
private
  FCompanyName: String;
  FID: String;
  FSET: String;
  FTestType: String;
  FWO_GUID: String;
public
  property CompanyName: String read FCompanyName write FCompanyName;
  property ID: String read FID write FID;
  property AnyFieldName: String read FSET write FSET;
  property TestType: String read FTestType write FTestType;
  property WO_GUID: String read FWO_GUID write FWO_GUID;
end;
  TJson.JsonToObject<TAddWorkOrder>(YouJsonText);
JACAmetekDenmark commented 10 months ago

Thankyou, have applied the attribute to name the component and that part is solved. However is your example manually defined or result of the generator ? if I run that short JSON text through the generator I still get a Property " &SET"

HemulGM commented 10 months ago

Thankyou, have applied the attribute to name the component and that part is solved. However is your example manually defined or result of the generator ? if I run that short JSON text through the generator I still get a Property " &SET"

I don’t see any difficulty in correcting such fields to be acceptable. Because the property name does not affect serialization

JACAmetekDenmark commented 10 months ago

you haven't defined the SET component which has to be published, in your example. That is the issue.

HemulGM commented 10 months ago

you haven't defined the SET component which has to be published, in your example. That is the issue.

It's not a mistake. And it will work. Check

JACAmetekDenmark commented 10 months ago

I think you misunderstood me. I need to generate the file ... not load it. How do I set "SET" = "AddWorkorder" if there is no public access?

JACAmetekDenmark commented 10 months ago

Name attribute does not work on arrays, [JSONName('Sensors'), JSONMarshalled(False)] FSensorsArray: TArray; [GenericListReflect] FSensors: TObjectList;

The node in the JSON file is always "sensors"

HemulGM commented 10 months ago

I think you misunderstood me. I need to generate the file ... not load it. How do I set "SET" = "AddWorkorder" if there is no public access?

image

HemulGM commented 10 months ago

You can set ANY property name. Its name will be taken from the private field!

JACAmetekDenmark commented 10 months ago

Apologies, i was only looking for the SET in the properties list, didn't see the AnyFieldName. Is there an issue with the Name attributes when applied to arrays?

Name attribute does not work on arrays,

[JSONName('Sensors'), JSONMarshalled(False)] FSensorsArray: TArray; [GenericListReflect] FSensors: TObjectList;

The node in the JSON file is always "sensors"

HemulGM commented 10 months ago

image

JACAmetekDenmark commented 10 months ago

Thankyou. strange both JSONName and JSONNameAttributey worked after I assigned the attributes to both the TArray and the TObjectList.

[JSONNameAttribute('Sensors'), JSONMarshalled(False)] FSensorsArray: TArray; [JSONNameAttribute('Sensors'), GenericListReflect] FSensors: TObjectList;

Very much appreciate your patience and help. All seems to work with JSON which will save me alot of time to finding another solution. regards James

JensBorrisholt commented 10 months ago

@JACAmetekDenmark I'm glad you got help. I was busy yesterday. You also spoked about "Is there a function to extract the contents into a TStringList so I can pretty-write to a file?"

Dig you got helt with that aswell? Or do you need a demo application.

JACAmetekDenmark commented 10 months ago

No we haven't touched on that. I use " TFile.WriteAllText('C:\Ametek\RTCRefresh\DelphiAddworker.JSON',AddWorkOrder.AsJson, TEncoding.UTF8);" to write to the file which works however unformatted and without indentation. So a demo or advice would be apprecated. regards James

JensBorrisholt commented 10 months ago

@JACAmetekDenmark can I have a copy of the file? Send it in a email, please, and I'll make you a demo.

HemulGM commented 10 months ago

No we haven't touched on that. I use " TFile.WriteAllText('C:\Ametek\RTCRefresh\DelphiAddworker.JSON',AddWorkOrder.AsJson, TEncoding.UTF8);" to write to the file which works however unformatted and without indentation. So a demo or advice would be apprecated. regards James

var JSON := TJSON.ObjectToJsonObject(YourObject);
try
  TFile.WriteAllText('C:\Ametek\RTCRefresh\DelphiAddworker.JSON', JSON.Format, TEncoding.UTF8);
finally
  JSON.Free;
end;
JensBorrisholt commented 10 months ago

@JACAmetekDenmark now I'm confused: Do you want to pretty print a JSON file (format with indentenration) or do you want do create json from a object and save that to a file?

For the latter Create (or generate) a unis that inheritets from TJsonDTO on you TJsonDTO decentant you have a property called AsJson, save that to at file.

TJSON.ObjectToJsonObject is the build in functioanllity, and have nothing to do with mit repo

JensBorrisholt commented 10 months ago

It seems like you are not using TJsonDTO in your exampels at all and thats where your problems starts

JACAmetekDenmark commented 10 months ago

Hi Jens, i inherit from TJsonDTO . here us a snippet.

TAddWorkOrder = class(TJsonDTO) private [JSONName('SET')] FSET: string; FTestType: string; [JSONName('WO_GUID')] FWOGUId: string; [JSONName('ID')] FId: string; [JSONName('Sensors'), JSONMarshalled(False)] FSensorsArray: TArray; [JSONName('Sensors'), GenericListReflect] FSensors: TObjectList; [JSONName('Scenario'), JSONMarshalled(False)]

[JSONName('ProcedureInfo')]
FProcedureInfo: TProcedureInfo;
function GetSensors: TObjectList<TSensors>;
function GetSibInputPorts: TObjectList<TSibInputPorts>;

protected function GetAsJson: string; override; published property &SET: string read FSET write FSET; property TestType: string read FTestType write FTestType; property Calibrator: TCalibrator read FCalibrator;

Regarding JSON file I want to simply save the AddWorkOrder json object to a JSON file in JSON format.

JensBorrisholt commented 9 months ago

@JACAmetekDenmark

I havent had time to look make sure the result are always formated but here is a smalle function for format a JSON file

function FormatJSON(json: String): String; var tmpJson: TJSONObject; begin tmpJson := TJSONObject.ParseJSONValue(json) as TJSONObject; Result := TJson.Format(tmpJson); FreeAndNil(tmpJson); end;

HemulGM commented 9 months ago

@JACAmetekDenmark

I havent had time to look make sure the result are always formated but here is a smalle function for format a JSON file

function FormatJSON(json: String): String; var tmpJson: TJSONObject; begin tmpJson := TJSONObject.ParseJSONValue(json) as TJSONObject; Result := TJson.Format(tmpJson); FreeAndNil(tmpJson); end;

Just TJsonValue