JSONを試してみた
December 17, 2010 – 12:41 pmいまさらという感じもしないでもないが、JSONを試してみた。JSONの使用は、今や、ちょっとしたWebプログラミングでは常識になっている。サーバーサイドのPHPで生成したJSONデータをHttpRequestでクライアントサイドに送信、クライアント(Web)側のScript上で受信したJSONデータをオブジェクトに変換しブラウザ上に表示するといった一連の手続きを具体的に試してみた。
このエントリーでは、JSONの特徴、フォーマットについて記述するとともに、今回、JSON理解のために作成した簡単なPHPプログラムそしてJavaScriptのソースを添付しておいた。
JSONとは何か?: 私の理解では、JSONは構造化されたデータ(オブジェクト、配列など)を異なるプログラム言語間で交換可能にするための一種のデータフォーマットということができる。これとは別に、この種のデータフォーマットとしてXMLがあるが、JSONはこれに比べて軽量で、扱いやすいという特徴があるようだ。
オブジェクトとか配列といった構造化されたデータを異なるプログラム言語間で直接(バイナリ形式で)やりとりしようとすると容易ではない。データの処理も煩雑になりがちである。この困難を解決する方法のひとつに、「構造化されたデータ」を標準的なフォーマットを持つテキストデータに変換し、それをやりとりすることが考えられる。個々のプログラム言語において、「構造化されたデータ」<-->「標準的なフォーマットを持つテキスト」の相互変換の仕組みを持たせておけば良い
JSON(Java Script Object Notation)はこの種のデータフォーマットのひとつである。「構造化されたデータ」とJSONデータ間の相互変換の仕組みも標準的なプログラム言語において整備されており、我々ユーザーは殆ど意識する必要はなさそうだ。このJSONデータはJavaScript(Standard ECMA-263 3rd Edition-December 1999)のサブセットをベースにしている。
JSONデータのフォーマット: JSONデータの特徴については、「Intoroducing JSON」にまとめられている。このなかにデータフォーマットが5種のダイアグラム形式で示されている。このダイアグラム、データフォーマットを実に良く表現している。以下である(「Introducing JSON」から転載):
JSON使用例: JSONデータフォーマットの有効性を理解するには具体的な例をみることが早道だ。
随分前になるが、アマゾンAPIを活用してAmazonから取得した書籍データ(XML)処理用のPHPプログラムを書いたことがある。このPHPプログラムでは、XMLデータをパース、連想配列化したデータとしたのち、これを処理しクライアント側(ブラウザ)で出力するHTMLデータを生成・送信していた。今回、このXMLデータをパースした「連想配列データ」をJSONに変換し、これをHttpRequestによりクライアントサイドに送信し、クライアント側で受信したJSONをオブジェクトに変換、これをブラウザ上に出力してみることにした。
クライアントサイドにおいてオブジェクト形式のデータを得ることにより、通信処理を介することなく複雑なデータ処理を行うことが可能になる。
以下、具体的なソースを示すことにする。処理の詳細はソースから理解できると思う。
なお、PHPにおける構造化データ(「連想配列」)のJSONデータへの変換は、PHP関数json_encode() (http://php.net/manual/en/function.json-encode.php ) を用い、また、JavaScriptにおけるJSONデータのパースにはJSON.parse()(http://www.json.org/js.html)を使用している。
test.php: サーバー側PHPプログラム(JSONデータの生成): 下記のPHPソースでは、アマゾンのASINコード「B0049W64JG」にかかわるAmazonのXML形式の商品データをパースしたデータ$parsed_xmlの一部(ItemAttributes以下)をjson_encodeを用いてJSONデータに変換している。
<?php header("Cache-Control: no-cache, must-revalidate"); require_once( "./AmazonDB.php" ); $amazonDB = new AmazonDB(); $request=$amazonDB->setRequestByAsin('B0049W64JG'); $parsed_xml = $amazonDB->getParsedXml($request); $json_text = json_encode($parsed_xml->Items->Item->ItemAttributes); echo $json_text . "\n"; $amazonDB = NULL; ?>
出力されたJSONデータ: 下記は生成されたJSONデータである。ここでは、見易すくするため、「改行」処理したものを示している:
{"Artist":"Mylene Farmer","Binding":"CD","EAN": "0602527555355","Format":["Import","from US"], "ListPrice":{"Amount":"2368","CurrencyCode": "JPY","FormattedPrice":"\uffe5 2,368"}, "NumberOfDiscs":"1","PackageDimensions": {"Height":"31","Length":"535","Weight":"18","Width":"496"}, "ProductGroup":"Music","ReleaseDate":"2010-12-14", "Title":"Bleu Noir","UPC":"602527555355"}
クライアント側HTML(Script含む)ソース:受信側のソースは以下である。ここでは、ブラウザ上の「Click Here」をクリックすることによりサーバーサイドのPHPプログラムを動作させ、そこで生成されたJSONデータを取得、これを適当なかたちでブラウザ上に出力する。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <!-- link rel="stylesheet" type="text/css" href="a.css" --> <style> body{ margin:3px; } </style> <title>JSON Trial</title> </head> <body> <h1>JSON Trial</h1> <div id="box">Click Here</div> </body> <script> function processJSON(JSONText) { var obj = JSON.parse(JSONText); var str = ""; for (var index in obj) { strings = index + " : " + obj[index]; if ( typeof obj[index] === "object" ) { obj02 = obj[index]; for (var index2 in obj[index]) { strings2 = index + " : " + index2 + " : " + obj02[index2]; if ( typeof obj02[index2] === "object" ) { obj03 = obj02[index2] for ( var index3 in obj[index2]) { strings3 = index + " : " + index2 + " : " + index3 + " : " + obj03[index3]; str = str + strings3 + "</br>"; } } else str=str+strings2+"</br>"; } } else str = str + strings + "</br>"; } document.getElementById("box").innerHTML = str; } function GetXmlHttpObject() {var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } function stateChanged() { var JSONText; if (xmlHttp.readyState==4) { var JSONText = xmlHttp.responseText; processJSON(JSONText); } } function getJSONText() { xmlHttp=GetXmlHttpObject(); if (xmlHttp==null) { alert("Your browser does not support AJAX!"); return; } var url="/json_test/test.php"; xmlHttp.onreadystatechange=stateChanged; xmlHttp.open("GET",url,true); xmlHttp.send(null); } function addEvent(node,type,handler){ if (document.addEventListener) { addEvent = function (node,type,handler) { node.addEventListener(type,handler,false); } } else { addEvent = function (node,type,handler) { node.attachEvent('on' + type, function(evt){ handler.call(node, evt); }); } } addEvent(node,type,handler); } var init = function() { var div = document.getElementById('box'); addEvent( div, "click", getJSONText ); } addEvent( window, "load", init ); </script> </html>
ブラウザ上の現れ:下記は上記したクライアントサイドHTMLソースが動作した際のブラウザ上の動作をしめしている。図の左側の「Click Here」部をクリックすることにより、これが右側のように変化し、JSONデータJavaScriptによる処理後の内容が出力されている。