QJson示例-向QJson实例中添加子结点的方法小结

QJson中添加结点主要有以下3种方式:

1、用Add函数

如我们要添加一个字符串类型的子结点:

var
   AJson:TQJson;
begin
AJson:=TQJson.Create;
AJson.Add('Name').AsString:='Jony smith';
...
FreeAndNil(AJson);
end;

Add函数有很多重载形式,我们先大概了解一下:

function Add(ANode: TQJson): Integer; overload;
function Add: TQJson; overload;
function Add(AName, AValue: QStringW;ADataType: TQJsonDataType = jdtUnknown): Integer; overload;
function Add(const AName: QStringW; AItems: array of const): TQJson; overload;
function Add(AName: QStringW; ADataType: TQJsonDataType): TQJson; overload;
function Add(AName: QStringW; AValue: Extended): TQJson; overload;
function Add(AName: QStringW; AValue: Int64): TQJson; overload;
function Add(AName: QStringW; AValue: Boolean): TQJson; overload;
function Add(AName: QStringW; AChild: TQJson): Integer; overload;
function AddArray(AName: QStringW): TQJson; overload;
function AddDateTime(AName: QStringW; AValue: TDateTime): TQJson; overload;
function AddVariant(AName: QStringW; AValue: Variant): TQJson; overload;
function Add(AName: QStringW): TQJson; overload; virtual;

(1)是直接添加一个Json结点到当前结点下,传递的是一个Json结点对象,注意添加后这个结点不应该再手工释放。

(2)是添加一个匿名的Json结点,一般用于添加数组的子元素,因为数组元素是没有名称的。

(3)添加一个指定名称和字符串值的结点,其中,AValue对象的值类型由ADataType参数指定,如果未指定,则QJson会自动检测并转换为匹配的类型。

(4)添加一个数组结点,结点的值为一个开放数组。如下面的代码就可以直接添加一个名为 Array 的数组结点,其中有 4 个元素,分别是整数 1 ,字符串 goods ,布尔值 true 和浮点数 3.4:

AJson.Add('Array', [1, 'goods', true, 3.4]);

(5)添加一个指定名称和类型的结点。

(6)添加一个指定名称和值的浮点数结点。

(7)添加一个指定名称和值的64位整数结点。

(8)添加一个指定名称和值的布尔结点。

(9)将一个已有的结点以指定的名称附加到当前结点上。

(10)添加一个数组类型的结点,等价于Add(AName,jdtArray)。

(11)添加一个指定名称和值的日期时间类型的结点。

(12)添加一个可变类型的子结点,类型会根据Variant值的内容自动确定。

(13)添加一个指定名称的空白子结点。这是我们常用的一种方法,然后通过AsXXX来为结点赋值,如:

AJson.Add('StringNode').AsString:='String Value';
AJson.Add('IntNode').AsInteger:=100;
AJson.Add('FloatNode').AsFloat:=1.34;

2、使用ForcePath函数来确保指定的路径存在。

ForcePath会检查指定的路径是否存在,如果不存在,会创建指定的路径。路径的分隔符可以是 “.” 、 “\” 、 “/” 三者之一,两个连续的分隔符会被忽略。QJson的路径按以下规则处理:

(1)、路径始终是以当前Json结点为根结点;

(2)、对象或者数组都可以使用数组方式来访问,下标从0开始。但如果省略数组的索引,则默认是第一个元素,如:

AJson.ForcePath('a.b.c[].d').AsString:='OK';

其结果如下:

{
  "a":{
    "b":{
      "c":[
        {
          "d":"OK"
        }
      ]
    }
  }
}

可以看到,c[].d实际被当成了c[0].d。

3、直接使用FromRtti/FromRecord方式添加。

此组函数是基于RTTI来自动将结构体或对象的数据生成对应的Json结构,注意一点,对象只会处理它的published成员,而结构是处理所有的成员。无论对象和结构体,不要出现循环定义的情况,否则会出现内存或堆栈溢出。

var
  ARec: TRttiTestSubRecord;
  AJson: TQJson;
begin
ARec.Int64Val := 1;
ARec.UInt64Val := 2;
ARec.UStr := 'Test String';
ARec.AStr := 'AnsiString';
ARec.SStr := 'ShortString';
ARec.IntVal := 3;
ARec.MethodVal := Button2Click;
ARec.SetVal := [{$IFDEF UNICODE}TBorderIcon.{$ENDIF}biSystemMenu];
ARec.WordVal := 4;
ARec.ByteVal := 5;
ARec.ObjVal := Button2;
ARec.DtValue := Now;
ARec.tmValue := Time;
ARec.dValue := Now;
ARec.CardinalVal := 6;
ARec.ShortVal := 7;
ARec.CurrVal := 8.9;
ARec.EnumVal := {$IFDEF UNICODE}TAlign.{$ENDIF}alTop;
ARec.CharVal := 'A';
ARec.VarVal := VarArrayOf(['VariantArray', 1, 2.5, true, false]);
SetLength(ARec.ArrayVal, 3);
ARec.ArrayVal[0] := 100;
ARec.ArrayVal[1] := 101;
ARec.ArrayVal[2] := 102;
SetLength(ARec.IntArray, 2);
ARec.IntArray[0] := 300;
ARec.IntArray[1] := 200;
AJson := TQJson.Create;
try
  AJson.Add('Record').FromRecord<TRttiTestSubRecord>(ARec);
finally
  FreeAndNil(AJson);
end;
end;

在使用此种方式添加结点时,相关注意事项请参考文章:QJson/QMsgPack RTTI 注意事项

 

分享到: