Javascript Object Notation: データ記述言語の1つ

JavaScript Object Notation(JSON、ジェイソン)はデータ記述言語の1つである。軽量なテキストベースのデータ交換用フォーマットでありプログラミング言語を問わず利用できる。名称と構文はJavaScriptにおけるオブジェクトの表記法に由来する。

JSON
Javascript Object Notation: 特徴, 表記方法, AjaxにおけるJSONの利用
拡張子.json
MIMEタイプapplication/json
種別Data interchange
国際標準IETF STD 90
RFC 8259
ECMA-404 2nd edition
ISO/IEC 21778:2017

特徴

JSONはウェブブラウザなどでよく使われているECMA-262, revision 3準拠のJavaScript (ECMAScript) をベースとしている。2006年7月RFC 4627で仕様が規定され、その後、何度か改定され、2017年12月14日にIETF STD 90およびRFC 8259およびECMA-404 2nd editionが発表された。MIMEタイプapplication/json拡張子はjsonとされた。

IETFおよびECMAおよびISOの仕様の改定の歴史

JSONはJavaScriptにおけるオブジェクト表記法のサブセットであるが、JavaScriptでの利用に限られたものではない。

JSONは単純であるので、特にAjaxの分野で利用が広がりつつある。JavaScriptでJSONをパースして読み込むには、文字列をJavaScriptのコードとして解釈させる eval 関数を作用させるだけでよい(ただし、セキュリティ上の問題があるうえ、ECMAScript 2018 までは U+2028 LINE SEPARATOR と U+2029 PARAGRAPH SEPARATOR の扱いがJavaScriptと互換性が無いため、JSON専用のパース関数の JSON.parse() を利用するべきである)。このように、広く普及しているウェブブラウザ搭載言語であるJavaScriptで簡単に読み込めるため、Ajaxの開発者達から注目を浴びることになった。

JavaScript言語以外でも、ほとんどの言語においてJSONは単純な処理で書き出しや読み込みができる。そのため、JSONは異なるプログラミング言語の間でのデータの受渡しには能率的である。ウェブアプリケーションの場合において、ウェブクライアントでのJavaScriptとのデータの受渡しなどはその最たる活用例と言える。プロセス間通信、マシン間通信においても、疎結合にするため、JSONで情報を受け渡しすることもある。

JSONの発見

ダグラス・クロックフォード英語版はJavaScriptのプログラマで、JSONを広めた一人だが、「The JSON Saga」と題したプレゼンテーション中で「自分はJSONと名付けたが、考案者ではなく、それ自体は“自然に”存在していたもので、早い例としては1996年にはNetscape Navigatorでデータ交換用に使われていた。だから“発見した”ということになるのだが、発見したのも自分が最初ではない」といったように述べている。以上のことを縮めて「JavaScriptのオブジェクト表記法からJSONが発見された。」と表現されている場合がある。

表記方法

JSONで表現するデータ型は以下の通りで、これらを組み合わせてデータを記述する。true, false, null などは全て小文字でなくてはならない。

  • オブジェクト(順序づけされていないキーと値のペアの集まり。JSONでは連想配列と等価)
  • 配列(データのシーケンス)
  • 数値(整数浮動小数点数
  • 文字列(バックスラッシュによるエスケープシーケンス記法を含む、ダブルクォーテーション"でくくった文字列)
  • 真偽値(truefalse
  • null

数値は10進法表記に限り、8進、16進法表記などはできない。また浮動小数点数としては 1.0e-10 といった指数表記もできる。

文字列は(JSONそれ自体と同じく)Unicode文字列である。基本的にはJavaScriptの文字列リテラルと同様だが、囲むのにシングルクォートは使えない。バックスラッシュによるエスケープがある。

配列はゼロ個以上の値をコンマで区切って、角かっこでくくることで表現する。例えば以下のように表現する:

["milk", "bread", "eggs"] 

オブジェクトはキーと値のペアをコロンで対にして、これらの対をコンマで区切ってゼロ個以上列挙し、全体を波かっこでくくることで表現する。例えば以下のように表現する:

{"name": "John Smith", "age": 33} 

ここで注意することはキーとして使うデータ型は文字列に限ることである。したがって、

{name: "John Smith", age: 33} 

という表記は許されない。この後者の表記はJavaScriptのオブジェクトの表記法としては正しいが、JSONとしては不正な表記である。

プログラム上で生成した文字列をJSONとして扱う場合、ダブルクォーテーション"を含む文字列を利用しなければいけないことに注意が必要である。なぜならコード上の"は文字列定義に利用される"であり、生成されるのはあくまで文字列helloであって文字列"hello"ではない。JSONの文字列型は後者であると定義されているので、以下のようにエラーを発生させる。利用時にはJSON生成関数(例 JavaScript: JSON.stringify)を利用する方がより安全である。

const invalidJSON = "hello"; const validJSON =  '"hello"';  JSON.parse(invalidJSON) // Thrown: // SyntaxError: Unexpected token h in JSON at position 0 JSON.parse(validJSON) // 'hello'  // safe JSON generation const output = JSON.stringify("hello") output // '"hello"' 

エンコーディング

RFC 8259より、閉じられたエコシステムで利用する場合を除き、文字コードはUTF-8でエンコードすることが必須 (MUST) となっている。ネットワークでJSONを送信する場合は、バイト順マークを先頭に付加してはいけない (MUST NOT)。

過去のIETFの仕様では、JSONテキストはUnicodeでエンコードするとされていた (SHALL)。デフォルトのエンコーディングはUTF-8であった。なお、単独の文字列でない限り最初の2文字は必ずASCII文字であるので、最初の4バイトを見ることにより、UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BEのいずれの形式でエンコードされているか判別できた。

AjaxにおけるJSONの利用

AjaxにおいてXMLHttpRequestで非同期にJSONでのデータを受け取る例を示す:

古典的な例

var the_object; var http_request = new XMLHttpRequest(); http_request.open( "GET", url, true ); http_request.onreadystatechange = function () {     if ( http_request.readyState == 4 ) {         if ( http_request.status == 200 ) {             the_object = eval( "(" + http_request.responseText + ")" );         } else {             alert( "There was a problem with the URL." );         }         http_request = null;     } }; http_request.send(null); 

新しい記法を利用した例

var the_object; var http_request = new XMLHttpRequest(); http_request.open( "GET", url, true ); http_request.responseType = "json"; http_request.addEventListener ( "load", function ( ev ) {     if ( ev.target.status == 200 ) {         the_object = http_request.response;     } else {         alert( "There was a problem with the URL." );     }     delete http_request; }); http_request.send(null); 

ここでいずれも、http_requestXMLHttpRequestオブジェクトであり、それを url にアクセスして返ってきたJSONで記述されたデータを the_object に格納される。いま、XMLHttpRequestを用いて実装をしたが、iframeなどの他の実装方法もある。また、JavaScriptライブラリprototype.jsではHTTPX-JSON ヘッダを利用して簡単にJSONデータの受渡しができる。

ライブラリ

JSONは多くのプログラミング言語で利用可能なライブラリーなどが提供されている。例えば、ActionScript, C, C++, C#, ColdFusion, Common Lisp, Curl, D, Delphi, E, Elixir, Erlang, Groovy, Haskell, Java, JavaScript (ECMAScript), Lisp, Lua, ML, Objective-C, Objective CAML, Perl, PHP, Python, R, Rebol, Ruby, Scala, Squeakなど。

ただし、テキストファイル、データを交換する手段を持つプログラミング言語であれば自力でパースして入力したり、フォーマット処理で出力は可能である。

JSONPath

JSONPath は JSON のクエリ式で、JSON の一部分を示すことが出来る。XMLXPath に対応するものとして Stefan Gössner が2007年に提案した。現在 IETF にて仕様が作成中である。様々なプログラミング言語でライブラリが実装されている。データベースでは、Oracle DatabaseMicrosoft SQL ServerMySQLPostgreSQLMongoDBRedisJSONなど広く採用されている。

例として、下記 JSON に対する、$.users[0:2].name の結果は ["Foo", "Bar"] になる。

{     "users": [         {"name": "Foo"},         {"name": "Bar"},         {"name": "Baz"}     ] } 

改行区切りのJSON

1行を1つのJSONとする改行区切りのJSONが複数の人によって提案されている。仕様は同一である。改行コードは \n を使わなければならないが、JSON の末尾に \r があっても無視されることから \r\n も利用可能である。

  • JSON Lines (JSONL) - 拡張子は jsonl
  • Newline delimited JSON (NDJSON)(旧称 Line delimited JSON, LDJSON)- 拡張子は ndjson 、MIMEタイプは application/x-ndjson

Comma-Separated Values よりも柔軟性がある。また、JSONの配列を使うよりも可読性があるうえ、ストリーミングにすることができる。以下は例。

{"ts":"2020-06-18T10:44:12","started":{"pid":45678}} {"ts":"2020-06-18T10:44:13","logged_in":{"username":"foo"},"connection":{"addr":"1.2.3.4","port":5678}} {"ts":"2020-06-18T10:44:15","registered":{"username":"bar","email":"[email protected]"},"connection":{"addr":"2.3.4.5","port":6789}} {"ts":"2020-06-18T10:44:16","logged_out":{"username":"foo"},"connection":{"addr":"1.2.3.4","port":5678}} 

JSON5

ECMAScript 5.1 に基づき、人間にとってより読み書きしやすい JSON5 が提案されている。コメントを書けたり、オブジェクトのキーは " が不要だったり、末尾カンマを付けられたりする。拡張子は json5 、MIMEタイプは application/json5 。

// コメント {a: 1,} 

他のデータ記述法との関係

    XML
    JSONはXMLと違ってマークアップ言語ではない。ウェブブラウザから利用できるという点では共通している。また両者とも巨大なバイナリデータを扱う仕組みがないことが共通している。
    YAML
    JSONはYAMLのサブセットと見なしてよい。YAMLにはブロック形式とインライン形式(フロー形式)の表記法があるが、JSONは後者にさらに制約を加えたものと捉えることができる。例えばRubyでは以下のようにしてJSONをYAMLとして読み込むことができる:
    the_object = YAML.load('{"name": "John Smith", "age": 33}') 
    YAML 1.1以前は、配列と連想配列の区切りをそれぞれ , のようにカンマ+スペースの形にすることでJSONのスーパーセットとなったが、YAML 1.2では区切り文字も互換となったため、正常なJSON文書においては公式に完全なスーパーセットとなった。僅かな相違点として、連想配列のキーがユニークであるべきことをJSONではSHOULDレベルで要請するのに対し、YAML 1.2ではMUSTレベルで要請している為、該当する異常データのエラーハンドリングに違いが出る可能性はある。

出典

関連項目

外部リンク

Tags:

Javascript Object Notation 特徴Javascript Object Notation 表記方法Javascript Object Notation AjaxにおけるJSONの利用Javascript Object Notation ライブラリJavascript Object Notation JSONPathJavascript Object Notation 改行区切りのJSONJavascript Object Notation JSON5Javascript Object Notation 他のデータ記述法との関係Javascript Object Notation 出典Javascript Object Notation 関連項目Javascript Object Notation 外部リンクJavascript Object NotationJavaScriptデータ記述言語プログラミング言語

🔥 Trending searches on Wiki 日本語:

種﨑敦美飯豊まりえ中谷潤人バンタム級島袋美由利ゴールデンウィーク近衛家目黒蓮熊本3歳女児殺害事件高嶋弘之ONE PIECE燕は戻ってこないキム・スヒョン (1988年生の俳優)WエンジンNintendo Switchゴイアニア被曝事故水上恒司転生貴族、鑑定スキルで成り上がる 〜弱小領地を受け継いだので、優秀な人材を増やしていたら、最強領地になってた〜ダウ90000豊臣秀吉悠木碧コードギアスシリーズの登場人物松本龍 (政治家)星麻琴僕のヒーローアカデミア黒羽快斗武居由樹釘宮理恵光る君へ山口一郎 (歌手)出川哲朗髙橋藍佐藤寿人山﨑福也橋本甜歌長谷川白紙加藤鮎子花山天皇生田絵梨花UEFAチャンピオンズリーグ早見沙織Yahoo! JAPANリサ (BLACKPINK)ゲンナジー・ゴロフキンつばさの党坂東龍汰鳥取ループ藤原道長大久保洋吉陰茎やす子宝塚歌劇団104期生ジョンリル・カシメロあぶない刑事安達祐実BABYMONSTER交響曲第9番 (ベートーヴェン)山中慎介ゲゲゲの鬼太郎涌井秀章新唯Da-iCEアメリカ同時多発テロ事件眞栄田郷敦涙の女王英語安田美沙子井上尚弥タトゥーFallout シリーズ黒川敦彦ソビエト連邦新垣結衣キム・ジウォン川谷拓三落合博満🡆 More