Lazarus中使用FPJSON进行JSON解析

技术分享 2020-10-01 4556 次浏览 次点赞

Delphi下JSON解析库比较多,常用的比如XE版本自带的System.JSON,第三方的SuperObject,XSuperObject,lkJSON等,使用教程在网上也比较多,但是发现在Lazarus下真正可以的JSON库真是少之又少,基本都是使用其自带的FPJSON。
使用方法我简单的代码示例一下,具体的使用方法可以参考freepascal官方网站的wiki https://wiki.freepascal.org/fcl-json

uses fpjson, jsonparser;
procedure TForm1.Button1Click(Sender: TObject);
var
  DataItem:TJSONObject;
  MyDataItem:TJSONArray;
  cc:string;
begin
  DataItem:=TJSONObject.Create;
  DataItem.add('name',UTF8ToAnsi('张抱'));
  DataItem.Add('mini',81556.32);
  DataItem.Add('maxdata',100);
  MyDataItem:=TJSONArray.Create;
  MyDataItem.Add('Tom');
  MyDataItem.Add('Mary');
  MyDataItem.Add('Bob');
  DataItem.Add('datalist',MyDataItem);
  cc:=DataItem.AsJSON;
  Memo1.Text:=cc;
end; 

最终在Memo1中生成的JSON串内容为:

{ "name" : "张抱", "mini" : 81556320000000007E+004, "maxdata" : 100, "datalist" : ["Tom", "Mary", "Bob"] }

这里有个需要注意的地方就是中文内容必须必须用UTF8ToAnsi函数进行一下转换,因为Lazarus的默认编码是UTF8。
还有另一个问题,你会发现mini我明明赋值的是81556.32,怎么输出变成科学计数法方式81556320000000007E+004了呐?这确实是一个有点严重的问题,如果和第三方进行数据交换可能存在兼容性的问题,这个问题我在使用Delphi的过程中从来也没遇到过。
下面重点来了,也就是写这篇文章的主要原因,怎么解决这个浮点数变成科学计数法,让它按正常的模式输出呐?开源的优势就体现出来了,找到FPJSON的源码文件fpjson.pp,跳至第1881行(FPC3.2.2的版本在2026行),你会发现如下代码

function TJSONFloatNumber.GetAsJSON: TJSONStringType;
begin
  Result:=AsString;
end;

只要将上面的 Result:=AsString; 改成 Result:=FloatToStr(FValue);就搞定了
最终的修改结果如下:

function TJSONFloatNumber.GetAsJSON: TJSONStringType;
begin
  Result:=FloatToStr(FValue);
end;

另外一点重要的是要删除原来的那些fpjson.ppu,fpjson.o文件,不然你的修改是不会生效的

PS:原来一直用Delphi现在打算新开发的小项目试着转用Lazarus,起初以为应该比较简单,真正用起来发现需要填的坑真的不少,就为了解决这个Json浮点数转换会默认科学计数法的问题,就耗费了近一周的时间.....
Key: How to resolve FPJSON JSONFloat convert scientific notation.


本文由 王守红 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论