简体   繁体   中英

Parse Json with SuperObject Delphi

I am new to JSON. I have the following JSON data and I don't know how to read the transaction object's id and amount values.

{
  "errorCode": 0,
  "errorMessage": "ok",
  "platform": 4,
  "order": {
    "id": "3425",
    "description": "test api",
    "amount": 1.39,
    "currency": "RON",
    "billing": {
      "country": null,
      "county": null,
      "city": null,
      "address": "address",
      "postal_code": null,
      "first_name": "fn",
      "last_name": "ln",
      "phone": "0000000000",
      "email": "me@mobilpay.com"
    },
    "shipping": null,
    "installments": null,
    "installments_sel": null,
    "bonuspoints": null,
    "products": {
      "item": {
        "id": null,
        "name": null,
        "description": null,
        "info": null,
        "group": null,
        "amount": null,
        "currency": null,
        "quantity": null,
        "vat": null
      }
    },
  "hash": "1BB262DEE09B15ED98B777A27740E16B1F00004E",
  "transaction": {
    "id": "461512",
    "amount": 1.39,
    "currency": "RON",
    "paymentUrl": "/qp/BdKQsV1d-DsGz0e-4Bkq2e",
    "current_payment_count": null
  },
  "params": null
}

I can read the errorCode and the errorMessage , but I don't know how to access the transaction id .

This is the code I have so far:

function TuDm_Athlos.ReadJson(ContentStr: TStream; var Order: TOrder): Boolean;
var
  workJson : ISuperObject;
begin
  Result := False;
  workJson := TSuperObject.ParseStream(ContentStr,False);
  Order.ErrorCode := StrToInt(workJson.S['errorCode']);
  order.ErrorMessage := workJson.S['errorMessage'];
  for workJson in workJson.O['transaction'] do
  begin
    Order.id := workJson.S['id'];
  end;
  Result := True;
end; 

You need to go deeper in the JSON object hierarchy. Based on code you've posted in comment:

function TuDm_Athlos.ReadJson(ContentStr: TStream; var Order: TOrder): Boolean;
var
  JSON: ISuperObject;
  Order: ISuperObject;
  Trans: ISuperObject;
begin
  Result := False;

  JSON := TSuperObject.ParseStream(ContentStr, False);
  if not Assigned(JSON) then
    Exit;

  Order := JSON.O['order'];
  if not Assigned(Order) then
    Exit;

  Trans := Order.O['transaction'];
  if not Assigned(Trans) then
    Exit;

  Order.ID := Trans.I['id'];
  Order.Amount := Trans.D['amount'];
  Order.ErrorCode := JSON.I['errorCode'];
  Order.ErrorMessage := JSON.S['errorMessage'];

  Result := True;
end;

I know this is a pretty old post, but I ran into the same thing. If you're a diligent developer, you might have range checking and overflow checking turned on while you're in development. The version of SuperObject you're working with may use a Hash for fast key comparisons that's defined as Cardinal. The Hash method assumes it can overflow the Cardinal type, but that overflow will trip range and overflow checking. To do it properly, you can modify the unit to use Int64 in place of Cardinal, then in the Hash method mask the calculated value to cut it back down to 32 bits, as in:

h := ( h*129 + ord(k[i]) + $9e370001 ) and $FFFFFFFF;

Same effect, no overflow.

只需通过溢出创建变量 h: UInt64 并且没有 AV。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM