delphi Json操作

Creating a Simple JSON Object

The following code segment demonstrates the creation of a simple JSON object containing one JSON pair. Once this object is created, its ToString method is invoked, assigning the returned string representation of the JSON object to the top memo field that appears on the main form.

procedure TForm1.WriteJSONObjectsClick(Sender: TObject); var   jo: TJSONObject; begin   Memo1.Clear;   try     jo := TJSONObject.Create;     jo.AddPair(TJSONPair.Create('Delphi',       TJSONString.Create('Supports JSON')));     Memo1.Lines.Add(jo.ToString);   finally     jo.Free;   end; end;

Because you can pass a JSON pair to the constructor of a TJSONObject, the first two lines of the try clause could have been replaced with a single line. Furthermore, since we passed a literal string to the TJSONString constructor, we could just as easily have passed the literal in place of the call to TJSONString.Create. The first two lines of the try clause could have been written like the following:

jo := TJSONObject.Create(TJSONPair.Create('Delphi','Supports JSON'));

Regardless of which technique you use, the result will look like the following:

{"Delphi":"Supports JSON"}

Creating JSON Numbers

You create JSON numbers using the TJSONNumber class. You can pass either a numeric literal or a string to the constructor of the TJSONNumber class. If you pass a string, you should ensure that it can be converted to a valid number. If the string value is not a number, you will end up with an invalid JSON value in your JSON object.

The following code, associated with the button labeled Create JSON Numbers, demonstrates how to create several different numbers. Notice that the argument to the TJSONNumber constructor in the second JSON pair is a string.

procedure TForm1.WriteJSONNumbersClick(Sender: TObject); var   jo: TJSONObject;   jp: TJSONPair; begin   Memo1.Clear;   try     jo := TJSONObject.Create;     jp := TJSONPair.Create('Integer', TJSONNumber.Create(10));     jo.AddPair(jp);     jo.AddPair(TJSONPair.Create('Float', TJSONNumber.Create('1001.23')));     jo.AddPair(TJSONPair.Create('Exponential', TJSONNumber.Create(5.1e3)));     Memo1.Lines.Add(jo.ToString);   finally     jo.Free;   end; end;
This code produces the result shown here. Notice that the string in the second JSON pair was converted to a floating point value. Also, since the exponential notation represented a number that could be converted to a conventional number, the TJSONNumber class performed that conversion. {"Integer":10,"Float":1001.23,"Exponential":5100}

Creating Booleans and Nulls

You create Boolean values using the TJSONTrue and TJSONFalse classes. Likewise, you create null values in your JSON object using TJSONNull. This is demonstrated in the following code example, which is associated with the button labled Creating JSON true, false, and null.

procedure TForm1.WriteJSONTrueFalseNullClick(Sender: TObject); var   jo: TJSONObject; begin   Memo1.Clear;   try     jo := TJSONObject.Create(TJSONPair.Create('True', TJSONTrue.Create));     jo.AddPair(TJSONPair.Create('False', TJSONFalse.Create));     jo.AddPair(TJSONPair.Create('Null',TJSONNull.Create));     Memo1.Lines.Add(jo.ToString);   finally     jo.Free;   end; end;

This code produces the following result:

{"True":true,"False":false,"Null":null}

Creating JSON Arrays

JSON arrays are a bit more involved that the other simple classes. When calling the constructor of a TJSONArray you can pass no parameters, a single TJSONValue, two TJSONValues, or two strings. If you pass one or more arguments, those passed objects will appear as the first objects in the array. If you pass no arguments, or need to add additional elements to the array, you can subsequently call the Add or AddElement methods of the TJSONArray class.

Use the Add method to add a TJSONObject or TJSONArray to the array, or to add a literal string, number, Boolean, or null. AddElement permits you to add any TJSONValue, and you must use AddElement if you want to add a value returned by the TJSONString, TJSONNumber, TJSONTrue, TJSONFalse, or TJSONNull constructors.

The use of Add and AddElement are shown in the following code, which is associated with the button labeled Create JSON Arrays.

procedure TForm1.WriteJSONArraysClick(Sender: TObject); var   ja: TJSONArray;   jo: TJSONObject; begin   Memo1.Clear;   ja := TJSONArray.Create;   try     ja.Add(TJSONObject.Create(TJSONPair.Create('Delphi','Supports JSON')));     ja.Add('Hello World');     ja.Add(TJSONArray.Create(TJSONNumber.Create(1),TJSONNumber.Create(2)));     (ja.Get(2) as TJSONArray).Add(3);     ja.Add(true);     ja.AddElement(TJSONFalse.Create);     ja.AddElement(TJSONNull.Create);     ja.AddElement(TJSONNumber.Create('-5.243e5'));   except     ja.Free;     raise;   end;   jo := TJSONObject.Create(TJSONPair.Create('result', ja));   jo.AddPair('One More','Last Pair');   try      Memo1.Lines.Add(jo.ToString);   finally     jo.Free;   end; end;

This code produces the following result:

{"result":[{"Delphi":"Supports JSON"},"Hello World",[1,2,3],true,false, null,-5.243e5],"One More":"Last Pair"}

Reading JSON Objects

JSON objects are text-based descriptions of data. This text is often transferred from an end point where the JSON object is created, to an end point where the data is consumed. Converting a JSON object to text is a simple matter of calling the ToString method of the top-level JSON object.

Converting a string that represents a JSON object into a JSON object is also straightforward. You do this by calling the ParseJSONValue class method of the TJSONObject class. This is shown in the following pseudo code:

var   jo: TJSONObject; begin   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try     // Do something with the JSON object   finally     jo.Free;   end;

As this code sample implies, the JSON object needs to be freed once you are done using it. Failure to do so will result in a memory leak by the top-level JSON object, as well as all of the JSON values that it contains.

Reading JSON Pairs

Every top-level JSON Object contains at least one JSON pair, and you must call the Get method of the TJSONObject class to retrieve a reference to this object.

There is a second method that returns a JSON pair from a JSON object, and that method is RemovePair. Note, however, that RemovePair both returns the JSON pair and removes it from the JSON object. Once removed, you become responsible for managing the life cycle of the removed pair, as well as all of the JSON values contained in that pair, if present. As a result, it is rare to use RemovePair when reading JSON values, unless your purpose is to change the JSON object.

When you call Get, you pass the zero-based ordinal position of the TJSONPair that you want to reference. Since all meaningful TJSONObjects have at least one TJSONPair, Get(0) should always return a TJSONPair. You can determine how many JSON pairs the top-level TJSONObject contains using the Size method.

Once you have a reference to a JSON pair, you can read the name part using the Value property of the JsonString property of the TJSONPair. The value part of the JSON pair is read using the Value property of the JsonValue property of the TJSONPair.

The use of ParseJSONValue and Get are demonstrated in the following code, which is associated with the button labeled Read JSON Object:

procedure TForm1.ReadJSONObjectClick(Sender: TObject); var   jo: TJSONObject;   jp: TJSONPair; begin   Memo2.Clear;   WriteJSONObjectsClick(nil);   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try     jp := jo.Get(0);     Memo2.Lines.Add('ToString: ' + jp.ToString);     Memo2.Lines.Add('JsonString: ' + jp.JsonString.Value);     Memo2.Lines.Add('JsonValue: ' + jp.JsonValue.Value);   finally      jo.Free;   end; end;

This code produced the following output:

ToString: "Delphi":"Supports JSON" JsonString: Delphi JsonValue: Supports JSON

The Get method is overloaded, permitting you to reference a JSON pair by name. For example, imagine that you want to refer to the JSON pair created by the WriteJSONObjectsClick event handler, with a name of Delphi and a value of Supports JSON. You can use code similar to the following:

procedure TForm1.ReadJSONObjectClick(Sender: TObject); var   jo: TJSONObject;   jp: TJSONPair; begin   Memo2.Clear;   WriteJSONObjectsClick(nil);   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try     if jo.Get('Delphi') <> nil then     begin       jp := jo.Get('Delphi');       //do something with the JSON par

Again, it is important to note that JavaScript is case sensitive. As a result, the string that you pass to the Get method is case sensitive as well. In the preceding code, if you had used 'delphi' as the parameter to the Get call, Get would have returned nil.

Reading String, Number, True, False and Null JSON Values

All TJSONValue instances have a Value property that returns a String representation of the value. For TJSONNumber, you will also find AsInt and AsDouble properties, which return the numeric value of the JSON number.

Using both the Value and AsDouble properties of a TJSONNumber is shown in the following code, which is associated with the button labeled Read JSON Numbers.

procedure TForm1.ReadJSONNumbersClick(Sender: TObject); var   jo: TJSONObject;   jp: TJSONPair;   jn: TJSONNumber; begin   Memo2.Clear;   WriteJSONNumbersClick(nil);   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try     jp := jo.Get(0);     Memo2.Lines.Add('ToString: ' + jp.ToString);     Memo2.Lines.Add('JsonString: ' + jp.JsonString.Value);     Memo2.Lines.Add('JsonValue: ' + jp.JsonValue.Value);     if jo.Get('Float') <> nil then     begin       jp := jo.Get('Float');       Memo2.Lines.Add('ToString: ' + jp.ToString);       Memo2.Lines.Add('JsonString: ' + jp.JsonString.Value);       jn := jp.JsonValue as TJSONNumber;       Memo2.Lines.Add('JsonValue: ' + FloatToStr(jn.AsDouble));     end;   finally      jo.Free;   end; end;

The preceding code produces the following output.

ToString: "Integer":10 JsonString: Integer JsonValue: 10 ToString: "Float":1001.23 JsonString: Float JsonValue: 1001.23

Reading TJSONTrue, TJSONFalse, and TJSONNull values are demonstrated in this event handler, which is associated with the button labeled Read JSON true, false, and null.

procedure TForm1.ReadJSONTrueFalseNullClick(Sender: TObject); var   i: Integer;   jo: TJSONObject;   jp: TJSONPair; begin   Memo2.Clear;   WriteJSONTrueFalseNullClick(nil);   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try     for i := 0 to jo.Size - 1 do     begin       jp := jo.Get(i);       Memo2.Lines.Add('ToString: ' + jp.ToString);       Memo2.Lines.Add('JsonString: ' + jp.JsonString.Value);       if (jp.JSONValue is TJSONTrue) or          (jp.JSONValue is TJSONFalse) or          (jp.JSONValue is TJSONNull) then         Memo2.Lines.Add('JsonValue: ' + jp.JsonValue.ToString)       else         Memo2.Lines.Add('JsonValue: ' + jp.JsonValue.Value)     end;   finally      jo.Free;   end; end;

This code produces this output:

ToString: "True":true JsonString: True JsonValue: true ToString: "False":false JsonString: False JsonValue: false ToString: "Null":null JsonString: Null JsonValue: null

Reading JSON Arrays

A JSON array contains one or more JSON values. You access the values of an array by position, calling Get and passing the zero-based ordinal position of the array element you want to access. Use the TJSONArray Size property to determine how many elements the array contains.

The following code demonstrates how to read the elements of a JSON array:

procedure TForm1.ReadJSONArraysClick(Sender: TObject); var   i, j: Integer;   jo: TJSONObject;   jp: TJSONPair;   ja: TJSONArray; begin   WriteJSONArraysClick(nil);   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try     for i := 0 to jo.Size - 1 do     begin       jp := jo.Get(i);       if jp.JsonValue is TJSONArray then       begin         Memo2.Lines.Add('JSONArray start');         ja := jp.JsonValue as TJSONArray;         for j := 0 to ja.Size - 1 do           Memo2.Lines.Add(ja.Get(i).ClassName + ': ' + ja.Get(j).ToString);         Memo2.Lines.Add('JSONArray end');       end       else         Memo2.Lines.Add(jp.ClassName + ': ' + jp.ToString);     end;   finally      jo.Free;   end; end;

The preceding code produces the following output:

ToString: "True":true JsonString: True JsonValue: true ToString: "False":false JsonString: False JsonValue: false ToString: "Null":null JsonString: Null JsonValue: null JSONArray start TJSONObject: {"Delphi":"Supports JSON"} TJSONObject: "Hello World" TJSONObject: [1,2,3] TJSONObject: true TJSONObject: false TJSONObject: null TJSONObject: -5.243e5 JSONArray end TJSONPair: "One More":"Last Pair"

A Generic Example

Using the techniques presented in this article you can parse any TJSONObject instance into its individual components. This is demonstrates in the following event handler, which uses recursion to walk a TJSONObject and output its values to the Memo shown in Figure 3.

procedure TForm1.ReadGenericJSONClick(Sender: TObject); var   jo: TJSONObject;   Indent: string; const   IndentSize = 2;
  procedure ParseJSONPairs(jo: TJSONObject); forward;
  procedure Indentation(Increase: Boolean);   begin    if Increase then      Indent := Indent +  '  '    else      Indent := copy(Indent, 1, Length(Indent) - IndentSize);   end;
  procedure WriteJSONValue(ancestor: TJSONAncestor);   var     jp: TJSONPair;     jv: TJSONValue;   begin     Memo2.Lines.Add(Indent + ancestor.ClassName);     if ancestor is TJSONPair then     begin       jp := TJSONPair(ancestor);       Memo2.Lines.Add(Indent + 'ToString: ' + jp.ToString);       Memo2.Lines.Add(Indent + 'JsonString: ' + jp.JsonString.Value);       if (jp.JSONValue is TJSONTrue) or          (jp.JSONValue is TJSONFalse) or (jp.JSONValue is TJSONNull) then         Memo2.Lines.Add(Indent + 'JsonValue: ' + jp.JsonValue.ToString)       else         Memo2.Lines.Add(Indent + 'JsonValue: ' + jp.JsonValue.Value)     end     else     begin       jv := TJSONValue(ancestor);       Memo2.Lines.Add(Indent + 'ToStrint: ' + jv.ToString);       Memo2.Lines.Add(Indent + 'Value: ' + jv.Value);     end;   end;
  procedure ParseJSONArray(ja: TJSONArray);   var     i: Integer;   begin     for i := 0 to ja.Size -1 do     begin       if ja.Get(i) is TJSONArray then       begin         Memo2.Lines.Add(Indent + 'JSONArray');         Indentation(True);         ParseJSONArray(ja.Get(i) as TJSONArray);         Indentation(False);       end       else if ja.Get(i) is TJSONObject then       begin         Memo2.Lines.Add(Indent + 'JSONObject');         Indentation(True);         ParseJSONPairs(ja.Get(i) as TJSONObject);         Indentation(False);       end       else         WriteJSONValue(ja.Get(i));     end;   end;
  procedure ParseJSONPairs(jo: TJSONObject);   var     i: Integer;     jv: TJSONValue;   begin     for i := 0 to jo.Size - 1 do     begin       jv := jo.Get(i).JsonValue;       if jv is TJSONOBject then       begin         Memo2.Lines.Add(Indent + 'TJSONObject');         Indentation(True);         ParseJSONPairs(jv as TJSONObject);         Indentation(False);       end       else if jv is TJSONArray then       begin         Memo2.Lines.Add(Indent + 'TJSONArray');         Indentation(True);         ParseJSONArray(jv as TJSONArray);         Indentation(False);       end       else         WriteJSONValue(jo.Get(i));     end;   end;
begin   if Memo1.Lines.Text = '' then   begin     ShowMessage('Display a JSON object in memo and try again');     exit;   end;   Indent := '';   Memo2.Clear;   jo := TJSONObject.ParseJSONValue(Memo1.Lines.Text) as TJSONObject;   try   ParseJSONPairs(jo);   finally     jo.Free;   end; end;

Figure 3. The JSONDemo project. The JSON that appears in the top memo field is parsed by the event handler attached to the button labeled Read Generic JSON.

Summary

JSON is a hierarchical, text-based mechanism for describing data. Similar to XML, though generally much shorter in length, JSON has quickly become a popular format for communicating data between processes.

In the next issue, I will demonstrate a number of advanced JSON techniques, along with a convenient tool for viewing JSON within Delphi's debugger.

Geef feedback:
CAPTCHA image
Vul de bovenstaande code hieronder in
Verzend Commentaar
 
posted @ 2014-10-04 19:26  LAOS  阅读(5843)  评论(0编辑  收藏  举报