動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)
- v0.2の動作を確認
関連 http://qiita.com/7of9/items/af34daf6c79ca8e004a7
http://qiita.com/7of9/items/5f7b93bcab19217bdd11
において複数行のJSONファイルが例示されていた。
C++ Builderで読込み処理を実装してみた。
v0.1 > 失敗編
JSONファイル (original)
info.json
{
"modify_head": [
"<script type='text/javascript'>",
"<!--",
" function drawSomeText(id) {",
" var pjs = Processing.getInstanceById(id);",
" var text = document.getElementById('inputtext').value;",
" pjs.drawText(text);}",
"-->",
"</script>"
],
"modify_body": [
"<input type='text' id='inputtext'></input>",
"<button onclick=drawSomeText('ExampleCanvas')></button>"
],
}
JSONファイル (modified)
info.json
{
"modify_head": [
"<script type='text/javascript'>",
"<!--",
" function drawSomeText(id) {",
" var pjs = Processing.getInstanceById(id);",
" var text = document.getElementById('inputtext').value;",
" pjs.drawText(text);}",
"-->",
"</script>"
],
"modify_body": [
"<input type='text' id='inputtext'></input>",
"<button onclick=drawSomeText('ExampleCanvas')></button>"
]
}
originalとの違いは最後の,
を削除したこと。
,
があると
TJSONObject *jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
がNULLを返す。
code v0.1
Unit1.cpp
//---------------------------------------------------------------------------
# include <vcl.h>
# pragma hdrstop
# include <memory>
# include <DBXJSON.hpp>
# include "Unit1.h"
//---------------------------------------------------------------------------
# pragma package(smart_init)
# pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const String kJsonFile = L"info.json";
const String kJsonKey = L"modify_head";
if (FileExists(kJsonFile) == false) {
return;
}
String jsonText = L"";
// 1. file read
std::unique_ptr<TStringList> fileSL(new TStringList);
fileSL->LoadFromFile(kJsonFile);
for(int idx=0; idx < fileSL->Count; idx++) {
jsonText = jsonText + fileSL->Strings[idx];
}
// 2. JSON parser
TJSONObject *jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
String item, value;
TJSONPair *pair;
for(int idx=0; idx < jsonObj->Size(); idx++) {
pair = jsonObj->Get(idx);
if (pair != NULL) {
String key = pair->JsonString->Value();
String txt = pair->JsonValue->Value();
RichEdit1->Text = txt;
}
}
jsonObj->Free();
}
//---------------------------------------------------------------------------
上記のコードでkeyは取得できるが、txtはmodify_head、modify_body両方に対してNULLとなった。
v0.2 > 成功編
参考情報
- http://stackoverflow.com/questions/14864170/how-to-parse-a-json-array-in-rad-studio
- http://www.gesource.jp/weblog/?p=4567
TJSONArrayを使うのはstackoverflowで分かり実装を試みたが、使い方が分からなかった。
山本隆さんのページを参考に解決した。
( TJSONArray* arr = dynamic_cast<TJSONArray*>(pair->JsonValue);
)。
情報感謝。
info.json
JSONファイル (modified)と同じ。
info.json
{
"modify_head": [
"<script type='text/javascript'>",
"<!--",
" function drawSomeText(id) {",
" var pjs = Processing.getInstanceById(id);",
" var text = document.getElementById('inputtext').value;",
" pjs.drawText(text);}",
"-->",
"</script>"
],
"modify_body": [
"<input type='text' id='inputtext'></input>",
"<button onclick=drawSomeText('ExampleCanvas')></button>"
]
}
code v0.2
Unit1.cpp
//---------------------------------------------------------------------------
# include <vcl.h>
# pragma hdrstop
# include <memory>
# include <DBXJSON.hpp>
# include "Unit1.h"
//---------------------------------------------------------------------------
# pragma package(smart_init)
# pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const String kJsonFile = L"info.json";
const String kJsonKey = L"modify_head";
if (FileExists(kJsonFile) == false) {
return;
}
String jsonText = L"";
// 1. file read
std::unique_ptr<TStringList> fileSL(new TStringList);
fileSL->LoadFromFile(kJsonFile);
for(int idx=0; idx < fileSL->Count; idx++) {
jsonText = jsonText + fileSL->Strings[idx];
}
// 2. JSON parser
TJSONObject *jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
for(int oi=0; oi < jsonObj->Size(); oi++) { // oi: outer index
TJSONPair *pair = jsonObj->Get(oi);
if (pair == NULL) {
continue;
}
if (pair->JsonString->Value() != kJsonKey) {
continue;
}
TJSONArray* arr = dynamic_cast<TJSONArray*>(pair->JsonValue);
String txt = L"";
for(int ii=0; ii < arr->Size(); ii++) { // ii: inner index
TJSONValue *lobj = arr->Get(ii);
txt = txt + lobj->Value();
}
RichEdit1->Text = txt;
}
jsonObj->Free();
}
//---------------------------------------------------------------------------
結果
成功。
modify_headの値を読み取った。