[QJSON] 使用 QJSON 的一些函数时的注意事项

QJSON 推出已经有相当一段时间了,经过这么多版本的更新,到了该回顾一下的时候。今天这篇文章算是一个简单的总结回顾,对大家使用 QJSON 过程中遇到的常见问题做一个简单的小结。

1、Add 系列函数

Add 系列函数用于添加一个子结点,它有 n 个重载的版本,最让大家疑惑的是下面的这个重载:

function TQJson.Add(AName, AValue: QStringW; ADataType: TQJsonDataType): Integer;

这个重载在使用时要注意,AName 是结点的名称,这个没有问题。AValue 是用字符串表达的新的 JSON 结点的值,它具体的含义取决于最后一个参数 ADataType,如果 ADataType 为 jdtUnknown(默认值),则此函数会认为是需要它自动去检测 AValue 的值的类型。而检测的规则是尝试转换为最贴切的类型,如:

AJson.Add(‘Int’,’100′);

这句代码将会创建一个整数类型的子结点,值为100,同样的,下面的代码:

AJson.Add(‘Float’,’1.23′);

AJson.Add(‘Bool’,’true’);

AJson.Add(‘Array’,'[1,2,3]’);

AJson.Add(‘Obj’,'{“a”:100,”b”:”nameb”}’);

将分别添加浮点、布尔、数组、对象类型的子结点。如果无法匹配默认的类型,则会将该值当成一个字符串值来处理。

使用 Add 系列函数时,需要注意一点:它不会检查是否有子结点(毕竟检查需要耗时,而且绝大多数应用环境不会重复),所以,需要调用者自己保证不会出现重复的名称。

2、ForceName 和 ForcePath 的区别

ForceName 是在当前结点下保证拥有一个指定名称的子结点,而 ForcePath 是在当前结点下,保证有一个符合指定路径要求的子结点。它俩的区别首先在于 ForcePath 会解析传进去的 APath 参数,然后根据 Path 的解析结果,逐级检查并确认存在指定名称的各级子结点,而 ForceName 会将传进来的 AName  参数,不会去解析里面的特殊字符,从而可以实现创建包含特殊名称的结点(如路径分隔符、中括号等 ForcePath 函数用于解析的特定字符)。如:

AJson.ForcePath(‘a.b’);

AJson.ForceName(‘a.b’);

前者会确保当前 AJson 对象下面有一个子对象,名为 “a”,而在该子对象下,存在一个结点,名为 “b”。后者则会确保当前结点下会有一个名为 “a.b” 的子对象。前者转换成 JSON 的话就是:

{

“a”:{

“b”:null

}

}

而后者转换成 JSON 的话,就是:

{

“a.b”:null

}

3、IndexOf  和 ItemByName 的区别

IndexOf 用于返回指定名称的子结点的索引,ItemByName 用于返回指定名称的子结点,实际上,ItemByName 内部调用了 IndexOf 函数,但它俩在解析结点名称时的区别还是有的:IndexOf 函数不会解析传入的名称,而 ItemByName 会解析传入的名称,以便能够通过索引来访问数组或对象的指定元素。也就是说,下面的代码:

AJson.IndexOf(‘[0]’);

AJson.ItemByName(‘[0]’);

前者是要查找名为 “[0]” 的子结点,后者则是要查找自己的第一个子元素。

4、AsJson、AsString、ToString、Encode、Value 的区别

首先,AsJson、AsString、ToString、Value 的基础都是 Encode 函数,但它们却略有区别:

  • AsJson 返回格式化的 JSON 字符串,但不会对内容进行转义处理;
  • AsString 在数据类型为 jdtNull 或 jdtUnknown 时返回空字符串,其它的情况等价于 Value;
  • Value 直接返回当前结点的字符串表达,我们可以认为其等价于 AsJson;
  • ToString 则是重载的基类的函数,等价于 AsString;
  • Encode 函数是用于让你自由控制将 JSON 对象转换为字符串的格式,是上述所有属性的基础。你可以自由控制其是否格式化 JSON 结果,是否转义及缩进方式字符串;

5、关于日期时间类型

日期时间类型不是 JSON 标准的数据类型,QJSON 只所以单独提出来,是为了方便使用,内部实际上是使用字符串来存贮的。所以,你判断其 DataType 时,可能得到的结果是 jdtString 而造成误判。而通过 IsDateTime 属性,可以判定这个值是否能够转换为日期时间类型。

6、关于二进制类型

JSON 同样不支持二进制数据类型,QJSON 提供了几个函数允许您按二进制方式访问。同样的,它在内部也会编码为字符串来存贮,编码的方式取决于 OnQJsonEncodeBytes 回调函数,如果不提供,则直接按十六进制编码,如果指定则按指定的规则处理。QJSON 单元直接提供了一个 EncodeJsonBinaryAsBase64 函数,来设置全局的 OnQJsonEncodeBytes 指向内部的 Base64 编码函数。同样,二进制数据类型由字符串转换回二进制需要提供一个 OnQJsonDecodeBytes 回调函数。

7、关于数组类型子元素的名称

JSON 的数组元素是没有名称的,所以,QJSON 在数组类型的结点保存时,如果你指定了元素的名称,保存时会忽略掉,所以它的名称是没有意义的,但你添加时指定了也不会报错。

8、关于 IgnoreCase 属性

IgnoreCase 默认是继承自全局的 JsonCaseSensitive 值。但对于具体的对象,您可以改变它,改变它将影响整个 JSON 结点树,但不会影响不在此树的其它 JSON 对象。

 

分享到: