JSON在RadStudio Delphi和C++ Builder上的应用

来源:互联网 发布:招聘数据分析报告 编辑:程序博客网 时间:2024/06/04 18:15

原文:《JSON with RadStudio Delphi or C++ Builder》

作者:Craig Chapman

地址:http://chapmanworld.com/2015/01/18/json-with-radstudio-delphi-or-c-builder/


  这是一篇介绍在 RadStudio Delphi 和 C++ Builder 上使用JSON的文章。

一、什么是JSON?

  JSON (JAVA脚本对象标记 JavaScript Object Notation) 是一种流行的结构数据封装格式。如果你熟悉XML格式,你可以把JSON看作能实现与XML同样功能的数据格式,虽然我们马上会看到它们之间的差异。

  JSON的名称可能会造成一些混乱,实际上它是与语言无关的数据表述格式,并不仅仅应用于JavaScript。之所以取这个名字的原因是,JSON是JavaScript首先介绍,并由JavaScript的Ajax应用程序使用而流行的。

  JSON格式的一些吸引人的特性包括:

1. 它是人类可读的。
  过去我们会把二进制数据转换成各种各样的编码解码包,而JSON只是文本,可以用ASCII或Unicode文本格式。

2. 它是轻量级的。
  相比其他的人类可读的封装,如XML或HTML格式,JSON显示得更加紧凑。这是因为JSON不使用诸如"填充"标签的形式。JSON还是重于非人类可读的封装方法,因为它的文本,通常是可变长度编码的Unicode格式。

3. 它的支持无处不在。
  JSON是第一个被各方都支持的JavaScript脚本(至少每个支持HTML5的浏览器都支持JSON),并被各种语言支持,从PHP,C,C++到Delphi等。

4. 它很容易解析。


二、JSON的结构

  我要介绍的是我对JSON的浅显理解。为了更准确和详细的了解JSON,你应该参考JSON文档标准 rfc-7159。
我们先来看一个简单的JSON例子:

    {
        "book": {
        "title": "Zen",
        "subtitle": "and The art of motorcycle maintenance.",
        "author": "Robert M Pirsig",
        "isbn": "9780061908019"
        }
    }


1. 数据对(Pairs)

   我们现在看到的是一本书的几个属性封装JSON的例子。每个数据块被表示为一个名称和值对,用冒号隔开。
    例如:
    "名字" : "值"
    "title" : "Zen"

  我们将这样一对名称和值的数据称为数据对(Pairs),名称和值之间用冒号隔开,数据对之间用逗号隔开。
  数据库开发人员可以把数据对看作一个字段或列。

2. 对象(Objects)

  你可以看到,我们的数据对由花括号包围,并在顶部还有一个名称book,看起来像是另一个数据对…
    "book": {
            ….
        }

  虽然这看起来像是一个数据对,它的右边没有一个用引号括起来的值,而是左花括号,数据对,然后一个右花括号。这种结构被称为一个对象。(JavaScript Object Notation)
  在这种情况下一个对象是一个数据对的集合。你可以从例子中看出,该对象被命名为"book",包含几个数据对,描述了一本书的属性。
  对象也可以嵌套,后面我们会看到。现在,我们已经可以看到嵌套样子,因为我们的对象"book"已经包含在另一对花括号内了,那也可以被视为一个对象,尽管它是一个没有名称的对象。这个对象必须作为父对象包含其他子对象。
  数据库开发人员可以把一个对象看作一个记录或行,在那里构筑形成它们之间的主从关系。

3. 多对象(Multiple Objects)

  如果我们想要多个对象该如何做?你可以很简单的用逗号分隔多个对象。还是用上面的例子,但这一次包含两本书…
{
    "book-1″: {
        "title": "Zen",
        "subtitle": "and The art of motorcycle maintenance.",
        "author": "Robert M Pirsig",
        "isbn": "9780061908019"
    },
    "book-2″: {
        "title": "Coding in Delphi",
        "subtitle": "",
        "author": "Nick Hodges",
        "isbn": "978-1941266038″
    }
}

  在这个例子中,这两个对象名为"book-1″和"book-2″,它们是由逗号分隔的两个完全不同的对象。
  它们的名称不同,虽然我可以给他们一样的名字,这将是一个糟糕的数据结构,如果我有两个对象命名为"book",我没有办法把它们区分开!
  谢天谢地,对于名字完全一样的对象,我们还可以使用数组…

4. 数组(Arrays)

  以上多本书的例子应该更正确地写为:
    {
        "books": [
            {
                "title": "Zen",
                "subtitle": "and The art of motorcycle maintenance.",
                "author": "Robert M Pirsig",
                "isbn": "9780061908019"
            },
            {
                "title": "Coding in Delphi",
                "subtitle": "",
                "author": "Nick Hodges",
                "isbn": "978-1941266038″
            } ]
    }

  在这个例子中,你可以看到,我们能够给多个联合的对象命名,这些多个联合的对象一对方括号中。这就是我们表示一个数据对象数组的形式,他们应该是一组有着同样结构类型的对象(同型),虽然这不是一个必需的要求。


三、在C++ Builder和Delphi中创建JSON对象

  到目前为止,我们已经看到三种JSON结构:数据对、对象、数组。在C++ Builder和Delphi中,分别对应三个类:TJSONPair、TJSONObject、TJSONArray。在接下来的例子中,我们将使用这三个类来创建我们的JSON结构。

现在我们写一些代码来创建这样的JSON结构:
    {
        "books": [
            {
                "title": "Zen",
                "subtitle": "and The art of motorcycle maintenance.",
                "author": "Robert M Pirsig",
                "isbn": "9780061908019"
            },
            {
                "title": "Coding in Delphi",
                "subtitle": "",
                "author": "Nick Hodges",
                "isbn": "978-1941266038″
            } ]
    }

  首先,新建一个应用程序,包含一个Button和一个Memo:
  (VCL 或 FMX 应用程序都可以,我喜欢用 VCL)

然后,引用JSON单元文件:
    C++:
    include <System.JSON.hpp>

    Delphi:
    uses
      System.JSON;

最后,在Button的OnClick事件中,加入下面代码:
    C++:

void __fastcall TForm1::Button1Click(TObject *Sender){// Create the outer JSON object which parents the others.TJSONObject *o = new TJSONObject();__try {// Create the books object, which contains the array of books...TJSONArray *a = new TJSONArray();// add the array to the object.o->AddPair("books",a);// Create the first bookTJSONObject *book = new TJSONObject();book->AddPair( new TJSONPair("title","Zen") );book->AddPair( new TJSONPair("subtitle","and The art of motorcycle maintenance.") );book->AddPair( new TJSONPair("author","Robert M Pirsig") );book->AddPair( new TJSONPair("isbn","9780061908019") );// Add the book to the arraya->AddElement(book);// Create the second bookbook = new TJSONObject();book->AddPair( new TJSONPair("title","Coding in Delphi") );book->AddPair( new TJSONPair("subtitle","") );book->AddPair( new TJSONPair("author","Nick Hodges") );book->AddPair( new TJSONPair("isbn","978-1941266038") );// Add the book to the arraya->AddElement(book);}__finally{  Memo1->Lines->Text = o->ToString();  o->Free();}}


    Delphi:

procedure TForm1.Button1Click(Sender: TObject);var  o: TJSONObject;  a: TJSONArray;  book: TJSONObject;begin  // Create the outer JSON object which parents the others.  o := TJSONObject.Create;  try    // Create the books object, which contains the array of books...    a := TJSONArray.Create();    // add the array to the object.    o.AddPair('books',a);    // Create the first book    book := TJSONObject.Create;    book.AddPair( TJSONPair.Create('title','Zen') );    book.AddPair( TJSONPair.Create('subtitle','and The art of motorcycle maintenance.') );    book.AddPair( TJSONPair.Create('author','Robert M Pirsig') );    book.AddPair( TJSONPair.Create('isbn','9780061908019') );    // Add the book to the array    a.AddElement(book);    // Create the second book    book := TJSONObject.Create;    book.AddPair( TJSONPair.Create('title','Coding in Delphi') );    book.AddPair( TJSONPair.Create('subtitle','') );    book.AddPair( TJSONPair.Create('author','Nick Hodges') );    book.AddPair( TJSONPair.Create('isbn','978-1941266038') );    // Add the book to the array    a.AddElement(book);  finally    Memo1.Lines.Text := o.ToString;    o.Free;  end;end;

  现在启动应用程序并按下按钮。你的Memo中应该填充JSON内容如下:

{"books":[{"title":"Zen","subtitle":"and The art of motorcycle maintenance.","author":"Robert M Pirsig","isbn":"9780061908019″},{"title":"Coding in Delphi","subtitle":"","author":"Nick Hodges","isbn":"978-1941266038″}]}

  噢,这都是一团丑陋的文本。如果你想看起来漂亮,那么可以粘贴到一个在线工具如jsonsh,制作成人类可读的样式!
  你可能已经注意到代码中的一些不寻常的东西。我们可以把数组名和方括号内的数组内容,看作一个数据对。因此,数组是一种特殊的数据对,左边和右边分别是数组名和数组的数据值。
  TJSONArray由TJSONPair组成,事实上,每一个对象都是一个数据对。


四、在C++ Builder和Delphi中解析JSON对象

  上面我们说了如何创建JSON结构和生成JSON字符串,现在反过来,让我们把JSON编码解析回结构,看下面代码…
  拖动第二个Button到窗口中,在其OnClick事件中加入下面代码:

    C++:

void __fastcall TForm1::Button2Click(TObject *Sender){TJSONObject *o = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::ASCII->GetBytes(Memo1->Lines->Text),0);__try {TJSONArray *a = (TJSONArray*) o->Get("books")->JsonValue;for (int idx = 0; idx < a->Size(); idx++) {TJSONObject *book = (TJSONObject*) a->Get(idx);for (int idy = 0; idy < book->Count; idy++) {ShowMessage( book->Pairs[idy]->JsonString->ToString() + ':' + book->Pairs[idy]->JsonValue->ToString() );}}}__finally {o->Free();}}

    Delphi:

procedure TForm1.Button2Click(Sender: TObject);var  o: TJSONObject;  a: TJSONArray;  book: TJSONObject;  idx: integer;  idy: integer;begin  o := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(Memo1.Lines.Text),0) as TJSONObject;  try    a := TJSONArray(o.Get('books').JsonValue);    for idx := 0 to pred(a.size) do begin      book := TJSONObject(a.Get(idx));      for idy := 0 to pred(book.Count) do begin        ShowMessage( book.Pairs[idy].JsonString.ToString + ':' + book.Pairs[idy].JsonValue.ToString );      end;    end;  finally    o.Free;  end;end;

  现在运行应用程序,先后单击button1、button2按钮。
  你将看到一系列消息框,显示了两本书的各属性的值。

  现在已经有创建和解析JSON数据的例子了,去写你自己的JSON应用程序吧!谢谢您的阅读!





0 0
原创粉丝点击