Open zuobaoquan opened 8 years ago
JsonDataObject uses Data-Objects and is per definition a DOM parser. Changing JsonDataObject to be a SAX parser won't happen in the near future as I personally don't need it (yet). But pull requests are welcome.
I'm with you. I think DOM parser is fine. What I suggested is actually more like a json string builder. e.g. writer := TJsonWriter.Create(stream, TEncoding.UTF8); // sample writer.StartObject; writer.WritePropertyName('name'); writer.WriteValue('Paul'); writer.EndObject; writer.Flush;
at present, it is done by two steps:
json.FromSimpleObject(obj); json.SaveToStream(stream);
An intermediate DOM is not necessary in this task. P.S. FromSimpleObject is close and very limited.
I don't need To/FromSimpleObject myself. I only added it to have at least something simple (and Delphi 2009 compatible) in the unit for others.
Your example of a TJsonWriter wouldn't be that hard to implement, so I may consider it.
A fluent interface JsonWriter is very welcome! It is now in my TODO list. I have a local fork of https://github.com/VSoftTechnologies/Delphi-Fluent-JSON that I have changed to use JsonDataObjects internally to add objects, but I'll probably rewrite it all to use only JsonDataObjects.
Righ now I'm using it mostly to write log as Json, like this:
Result := CreateJsonObject
.Text(MODULE_MEMBER, FModuleName)
.Text(TASK_MEMBER, FTaskName)
.Text(ERROR_MEMBER, ErrMsg)
.Text(EXCEPTION_MEMBER, E.ClassMessage)
.Number(SYS_ERR_CODE_MEMBER, SysErrorCode)
.Text(SYS_ERR_MSG_MEMBER, SysErrorMessage(SysErrorCode))
.Text(STACK_TRACE_MEMBER, GetStackTrace(ExceptAddr))
.ToString;
For my fluent interface I have methods like:
function Obj: IJsonBuilder; overload;
function Obj(const name: string): IJsonBuilder; overload;
function Obj(const name: string; value: TObject): IJsonBuilder; overload;
function Text(const name: string; const value: string): IJsonBuilder; overload;
function Text(const name: string; const value: string; const Args: array of const): IJsonBuilder; overload;
function Number(const name: string; const value: Double): IJsonBuilder; overload;
I also have methods for Array, Null, and need to implement for Date, so it will be handled by the overloaded method.
It is often not necessary to create DOM (JsonObject) when serializing objects to a stream. It is more efficient to expose a public TJsonWriter to perform such task.
TJsonOutputWriter is used internally so far. Also, UTF8String should be considered in this part.