Tomasz Sipel
Tomasz Sipel

Reputation: 1

How to show encoded Unicode string from JSON to TDBGrid?

Using Embarcadero C++Builder XE3 with Indy TIdHTTP component.

From some API, I get a String response:

{"Items":[{"Id":"jp-lp|o4nfz4IB6j9TcSaTQGxD","Type":"Container","Text":"106-0031 \u6771\u4EAC\u90FD \u6E2F\u533A \u897F\u9EBB\u5E03","Highlight":"0-3,4-8","Description":" - 991 Addresses"}]}

So, I guess either Indy or C++Builder itself convert it wrongly.

I read the string and it contains what's above.

When I parse it with TJSONObject and get the value of Text, eg:

String val = myJSONObject.get("Text")

And show it by the ShowMessage() function, everything works fine (also, under the debugger by inspecting the value), and I see a correctly presented message:

106-0031 東京都 港区 西麻布

As soon as I pass it to a TField of my TDataSet using the AsString or AsWideString property, and using ShowMessage(TField.AsString), I see question marks instead of real Unicode characters.

Also, when attaching my TDataSet to TDBGrid, I see the same question marks in the fields.

My string now looks like that:

106-0031 ??? ?? ???

I was trying to use different datasets, different versions of grids, numerous conversions.

It only worked fine for TStringGrid when I provide cell values using TStringGrid.Cells[][], so I assume that might be the problem. However, presenting the result with TStringGrid is not an option. I need to present my result in either TDBGrid / TJvDBUltimGrid / TDBAdvGrid, so it has to go through TDataSet.

All DataSets I use are in-memory sets, ie TClientDataSet, etc.

Here is the code:

String response = "{\"Items\":[{\"Id\":\"jp-lp|o4nfz4IB6j9TcSaTQGxD\",\"Type\":\"Container\",\"Text\":\"106-0031 \\u6771\\u4EAC\\u90FD \\u6E2F\\u533A \\u897F\\u9EBB\\u5E03\",\"Highlight\":\"0-3,4-8\",\"Description\":\" - 991 Addresses\"}]}";
TJSONObject *jsResponse = static_cast<TJSONObject *>(TJSONObject::ParseJSONValue(response));
String Key("Items");
TJSONArray *jsItems;
for(int i = 0; i < jsResponse->Size(); ++i){
  String CurrKey(jsResponse->Get(i)->JsonString->Value());
  if(CurrKey == Key){
    jsItems = ((TJSONArray *)(NativeJSON->Get(i)->JsonValue));
    break;
  }
}
for (int i = 0; i < jsItems->Size(); ++i){
  TJSONObject* currItem = ((TJSONObject *)jsItems->Get(i));
  String correctlyDisplayedValue;
  for(int i = 0; i < currItem->Size(); ++i){
    String CurrKey(currItem->Get(i)->JsonString->Value());
    if(CurrKey == "Text"){
      correctlyDisplayedValue = ((String)((TJSONString *)(NativeJSON- >Get(i)->JsonValue)));
      break;
    }
  }
  ShowMessage(correctlyDisplayedValue); //prints out correctly
  memoDS->Active = true;
  memoDS->FieldByName("Text")->AsString = correctlyDisplayedValue;
  ShowMessage(memoDS->FieldByName("Text")->AsString); // displayed message is one with "??? ?? ???"
}

And there is my memoDS definition in .dfm unit:

 object memoDS: TkbmMemTable
     DesignActivation = True
     AttachedAutoRefresh = True
     AttachMaxCount = 1
     FieldDefs = <     
       item
         Name = 'TEXT'
         DataType = ftWideString
       end>
     IndexDefs = <>
     SortOptions = []
     PersistentBackup = False
     ProgressFlags = [mtpcLoad, mtpcSave, mtpcCopy]
     LoadedCompletely = False
     SavedCompletely = False
     FilterOptions = []
     Version = '7.76.00 Standard Edition'
     LanguageID = 0
     SortID = 0
     SubLanguageID = 1
     LocaleID = 1024
     AutoUpdateFieldVariables = False
     Left = 566
     Top = 6
     object strngfldAddrSearchText: TStringField
       FieldName = 'TEXT'
       Size = 255
     end
   end

Upvotes: 0

Views: 103

Answers (0)

Related Questions