Поддержка JSON довольно сильно интегрирована в mORMot. Возможности сериализации весьма широки, хотя не все из них находятся на поверхности.
Замечательно, что сериализация объектов в mORMot построена на основе RTTI, даже для старых версий Delphi. Сериализуемые свойства объектов должны быть объявлены как published.
Сериализация простых свойств (число, дата, строка, булевский тип) выполняется автоматически и каких-либо cложностей не представляет.
Сериализация структурных свойств (запись, массив записей и массив значений) также выполняется автоматически, но по умолчанию происходит их преобразование в Base64-строку. Если требуется получить читаемое представление, то надо написать несложные функции обратного вызова Reader/Writer или использовать массивы предопределенных типов.
В прилагаемом исходнике я специально не использовал предопределенные типы массивов для того, чтобы продемонстрировать возможность переключения представления данных.
Также обратите внимание, что перед десериализацией JSON-строка предварительно копируется в промежуточный буфер. Это необходимо, т.к. данные в буфере изменяются при десериализации.
SetString(s,pchar(pointer(JsonString)),Length(JsonString)); JsonToObject(List, pointer(s), isValid);
Если JSON-строка после десериализации в программе не используется, то этот код можно сократить:
JsonToObject(List, pointer(JsonString), isValid);
Немного покопавшись во внутренностях mORMot, можно обнаружить даже способ сериализации обычных записей или массивов записей. Как и при работе с объектами, в этом случае удается получить представление полей записи и в виде упорядоченного массива неименованных значений, и в виде AV-пар.
Добавление
Если ваш SynCommons.pas датирован 28.02.2013 или позднее, то вы можете немного упростить сериализацию массивов записей, например:
procedure TForm1.bRecordArrayToJsonClick(Sender: TObject); var ra: TDynRecordArray; wr: TTextWriter; i: integer; begin; SetLength(ra,5); for i:=0 to Length(ra)-1 do FillRecord(ra[i], i); wr:=TTextWriter.CreateOwnedStream; try wr.AddDynArrayJson(TypeInfo(TDynRecordArray),ra); JsonString:=wr.Text; finally wr.Free; end; Memo1.Text:=UTF8ToString(JsonString); end; procedure TForm1.bRecordArrayFromJsonClick(Sender: TObject); var ra: TDynRecordArray; isValid: boolean; s: RawUTF8; i: integer; begin; Memo2.Lines.Clear; if JsonString<>'' then begin; SetString(s,pchar(pointer(JsonString)),Length(JsonString)); isValid:=DynArrayLoadJSON(ra,pointer(s),TypeInfo(TDynRecordArray))<>nil; if not isValid then Memo2.Lines.Text:='invalid JSON string' else for i:=0 to Length(ra)-1 do ShowRecord(ra[i], Memo2); end; end;
Прикрепленный файл | Размер |
---|---|
JsonProj.zip | 6.04 кб |
Comments (5)
обратите внимание на то, что
обратите внимание на то, что модуль SynCommons.pas не является кросс-платформенным. Возможно, кому-то поможет избежать ошибок.
Буффер
А нельзя сделать просто?
S := JsonString; UniqueString( s );
Буффер
Конечно, можно.
Delphi xe3
Dont work in delphi xe 3 update 2 , i have to add
SynCommons. in ttextwrite but record to json product this
"bQEAAJP+////////AAAAAABAQkAXU+ovQ2DkQApkAGEAeQAvADMA"
roberio.praciano@gmail.com
Brazil
Record format
Do you set radio button named "Record (array) format"?