JSON 関数の使い方
FileMaker Pro には、REST API を使用して JSON 形式のデータを転送する Web サービスなど、他のソースの JSON データをカスタム App で解析および変更できるようにするテキスト関数がいくつか用意されています。
JSON データ形式の詳細については、json.org を参照してください。
JSON データの書式設定
JSON データでは要素間のスペースや改行は必要ありません。ただし、問題をデバッグするときにデータを読みやすくするには、JSON データの例に示すようにタブや改行コード文字を追加する JSONFormatElements 関数を使用します。
JSON データの解析
次の JSON 関数を使用して JSON データを解析します。つまり、キー、値、JSON オブジェクト全体 (さらに処理が可能な配列) を取得します:
-
JSONGetElement – JSON データで要素 (オブジェクト、配列、または値) のクエリーを実行します
-
JSONListKeys – JSON データ内のオブジェクト名 (キー) または配列索引の一覧を表示します
-
JSONListValues – JSON データ内の値の一覧を表示します
これらの関数の 1 番目の引数 json
では、処理対象の有効な JSON データを含むテキストフィールド、変数、またはテキスト式を指定します。
2 番目の引数キーまたは索引またはパス
では処理対象の JSON データの位置を指定します:
-
キー – JSON オブジェクト内のキーの名前
-
索引 – JSON 配列内の要素の索引 (1 番目の要素の索引は 0)
-
パス – キー名、配列索引、またはこの両方の階層文字列
キーまたは索引またはパス
引数ではドット表記とカッコ表記の 2 種類の構文がサポートされます。
|
意味 |
|
ドット表記 | カッコ表記 | |
---|---|---|
|
|
1 番目の文字である場合はルートレベル (ドット表記ではオプション) |
|
|
ルートレベルの配列の索引 n の位置にある要素 |
|
|
ルートレベルの名前というオブジェクトのキー |
|
|
名前 C というオブジェクト、名前 B および名前 A の子孫 |
|
|
名前 A オブジェクトの配列の 1 番目の要素、ネストされた配列セットの 3 番目のレベル |
|
|
配列の最後の要素 |
|
|
配列の最後の要素の後の位置。JSONSetElement 関数で使用して配列の末尾に要素を追加します。 |
ドット表記とカッコ表記の違いとして、カッコ表記ではピリオド (.) を使用してキー名を区切るのではなく、シングルクォーテーション (') とカッコ ([]) でキー名を囲みます。
キーまたは索引またはパス
ではどちらの表記も使用できます。ただし、キー名にピリオドが含まれている場合、JSON パーサにキー名全体を正しく識別させるためにカッコ表記を使用する必要があります。たとえば、JSON オブジェクトのルートにあるキーが "レイアウト.応答" である場合、
キーまたは索引またはパス
は "['レイアウト.応答']" になります。
次のサンプルスクリプトは JSON 配列内の製品ごとにレコードを作成します。$$JSON 変数に JSON データの例が格納されているとすると、スクリプトは JSONListValues を使用して製品配列の内容を値の一覧として取得し、ValueCount を使用して一覧内の製品の数を調べます。ループするたびに製品のレコードを作成し、GetValue を使用して一覧から製品の JSON オブジェクトを取得して、フィールドを JSONGetElement で取得した値に設定します。JSON 関数は渡された JSON オブジェクト全体を解析するので、何度も繰り返されるループ内の小さい JSON オブジェクトに JSON 関数を使用するとより効率的です。
変数を設定 [$ProductList ; 値:JSONListValues ($$JSON ; "ベーカリー.製品")]
変数を設定 [$ProductCount ; 値: ValueCount ($ProductList)]
変数を設定 [$i ; 値: 1 ]
If [$ProductCount > 0]
Loop [フラッシュ: 常に]
新規レコード/検索条件
変数を設定 [$Product ; 値: GetValue ($ProductList ; $i)]
フィールド設定 [製品::ID ; JSONGetElement ($Product ; "id")]
フィールド設定 [製品::価格 ; JSONGetElement ($Product ; "価格")]
フィールド設定 [製品::在庫 ; JSONGetElement ($Product ; "在庫")]
レコード/検索条件確定 [ダイアログあり: オフ]
変数を設定 [$i ; 値: $i + 1]
Exit Loop If [$i > $ProductCount]
End Loop
End If
JSON データ要素の変更と追加
JSON データの値を変更する場合や要素を追加する場合は JSONSetElement 関数を使用します。この関数の json
およびキーまたは索引またはパス
引数はJSON データの解析で説明したとおりに機能します。キーまたは索引またはパス
で既存の要素を指定した場合はその要素の値が変更され、要素が存在しない場合は新しい要素が追加されます。
JSONSetElement は指定された要素に値
引数を設定します。単純な文字列や数値から複雑なオブジェクトや配列まで、すべての有効な JSON 値を指定できます。
タイプ
引数では値
のデータタイプを指定して、JSON パーサが各データタイプを扱うときの厳格なルールに従うようにします。サポートされるデータタイプについては JSONSetElement 関数を参照してください。有効な JSON 要素としてすでにフォーマット済みの json
にデータを挿入するには、type
を JSONRaw
に設定します。
次の例では新製品のキー/値ペアを空の JSON オブジェクトに追加します。次に新しいオブジェクトを $$JSON 変数の製品配列の末尾に追加します (JSON データの例を参照してください)。
変数を設定 [$NewProduct ; 値:
JSONSetElement ("{}" ;
["id" ; "FB4" ; JSONString] ;
["名前" ; "バニラケーキ" ; JSONString] ;
["価格" ; 17.5 ; JSONNumber] ;
["在庫" ; 12 ; JSONNumber] ;
["カテゴリ" ; "ケーキ" ; JSONString] ;
["特売" ; true ; JSONBoolean]
) ]
変数を設定 [$NextIndex ; 値:
ValueCount (
JSONListKeys ($$JSON ; "ベーカリー.製品")
) ]
変数を設定 [$$JSON ; 値:
JSONSetElement (
$$JSON ; "ベーカリー.製品[" & $NextIndex & "]" ; $NewProduct ;
JSONObject
) ]
JSON 要素を作成するもう一つの JSON 関数は JSONMakeArray 関数です。値の一覧を JSON 配列に変換します。異なる書式のデータを受け取るために、この関数では各値を区切る文字と使用する JSON データタイプを指定できます。
JSON データ要素の削除
要素を削除するには JSONDeleteElement 関数を使用します。この関数の json
およびキーまたは索引またはパス
引数はJSON データの解析で説明したとおりに機能します。キーまたは索引またはパス
引数では json
の既存の要素を指定する必要があります。
次の例では $$JSON 変数の "ID" キーの値が "FB3" の製品配列の要素を削除します (JSON データの例を参照してください)。
変数を設定 [$ProductCount ; 値:
ValueCount (
JSONListKeys ($$JSON ; "ベーカリー.製品")
) ]
変数を設定 [$i ; 値:0]
If [$ProductCount > 0]
Loop [フラッシュ: 常に]
変数を設定 [$ID ; 値:
JSONGetElement ($$JSON ; "ベーカリー.製品[" & $i & "]id")]
If [$ID = "FB3"]
変数を設定 [$$JSON ; 値:
JSONDeleteElement ($$JSON ; "ベーカリー.製品[" & $i & "]")]
現在のスクリプト終了 [テキスト結果:0]
End If
変数を設定 [$i ; 値: $i + 1]
Exit Loop If [$i ≥ $ProductCount]
End Loop
End If
JSON データのエラー処理
json
引数の解析中にエラーが発生した場合は、JSON 関数は「?」に続けて JSON パーサからのエラーメッセージを返します。
たとえば、JSON データの例の「ベーカリー」キーの後に「:」が見つからない場合は、計算式
JSONGetElement ($$JSON ; "ベーカリー.製品[0]id")
は次のエラーメッセージを返します:
? * Line 3, Column 2
Missing ':' after object member name
* Line 13, Column 5
Extra non-whitespace after JSON value.
JSON データを使用する前に有効かどうかを判定するには、JSONFormatElements 関数を使用して先頭の文字が「?」であるかどうかをテストします。例:
変数を設定 [$result ; 値:JSONFormatElements ($$JSON)]
If [Left ($result ; 1) = "?"]
# $$JSON に無効な JSON データが含まれています。
End If
別の方法として、JSON データを使用する前に有効かどうかを判定するには、JSONGetElementType 関数を使用してオブジェクト全体が JSON オブジェクトであるかどうかをテストします。例:
変数を設定 [$result ; 値:JSONGetElementType ($$JSON, "")]
If [$result ≠ JSONObject]
# $$JSON に無効な JSON データが含まれています。
End If
Web サービスからの JSON データの取得
[URL から挿入] スクリプトステップを使用して Web サービスへのアクセス、取得する情報に対する引数指定、HTTP ヘッダの送受信、変数またはフィールドへの結果の保存を行います。
たとえば、あるベーカリーで顧客が購入できる製品の一覧を、REST API を使用して JSON 形式で作成します。次の例では、本日の特売一覧を $$JSON 変数に格納された JSON データとして返します:
変数を設定 [$url ; "https://bakery.example.com/rest/api/products"]
URL から挿入 [ダイアログあり: オフ; ターゲット: $$JSON ; $url ; SSL 証明書の検証; cURL オプション: "--data 一覧 = 特売"]
$$JSON に格納されて返されるデータについては、JSON データの例を参照してください。
FileMaker Pro には、一部の REST API で必要な文字エンコードと暗号化署名を処理するユーティリティ関数もいくつか用意されています:
JSON データの例
次の例では、JSON データに「ベーカリー」オブジェクトが含まれています。「ベーカリー」オブジェクトは 3 つの「製品」オブジェクトを含み、それぞれがキー/値ペアを複数持ちます。
{
"ベーカリー" :
{
"製品" :
[
{
"id" : "FB1",
"名前" : "ドーナツ",
"価格" : 1.99,
"在庫" : 43,
"カテゴリ" : "パン",
"特売" : true
},
{
"id" : "FB2",
"価格" : 22.5,
"名前" : "チョコレートケーキ",
"在庫" : 23,
"カテゴリ" : "ケーキ",
"特売" : true
},
{
"id" : "FB3",
"価格" : 3.95,
"名前" : "バゲット",
"在庫" : 34,
"カテゴリ" : "パン",
"特売" : true
}
]
}
}
メモ
-
JSON パーサは配列内の要素の順序は維持しますが、オブジェクト内の要素の順序は維持しません。そのため、JSON 関数は指定した順序とは異なる順序でオブジェクトの要素を返すことがあります。
-
JSON データの分数値には小数点記号としてピリオド「.」を使用する必要があります。これは、コンピュータのシステム形式や FileMaker Pro ファイルの作成時に使用された形式で指定されている記号とは無関係です。