Flashゲームプログラミング講座 for ActionScript3.0

 

JSON とは?

 


■JSON とは?


JSON は、「JavaScript Object Notation」の略で「ジェイソン」といいます。
 
テキストフォーマットの一種です。シンプルで軽量です。
 
JSON は、null、真偽値、数値、文字列、配列、オブジェクト(連想配列)のデータを、文字列で表現できます。
 
配列とオブジェクト(連想配列)は、ネスト(入れ子)構造で表現する事ができます。
 
ECMAScript 系の言語であれば、「オブジェクト(ECMAScript)」と「JSON 文字列」の相互変換を、簡単に行うことができます。
 
他言語で扱う場合でも、XML と比べて比較的仕様が簡単なので、導入が容易でしょう。
 


 

JSON のフォーマットについて

 


■JSON のフォーマットについて

 
ECMAScript にて、配列とオブジェクトを作成したい場合、以下の様なリテラル表記を使用することができます。
 
■ECMAScript で配列を作成する場合
 
初期データを格納しつつ、配列を作成するには、配列リテラルを使用します。
 
初期データを格納して配列を作成

var ary = [true , false , 0 , 1 , 2 , 0.345 , "あ" , "い"];
 
■ECMAScript でオブジェクトを作成する場合
 
初期データを格納しつつ、オブジェクトを作成するには、オブジェクトリテラルを使用します。
 
初期データを格納してオブジェクトを作成

var obj = {
	a : true,
	b : false,
	c : 0,
	d : 1,
	e : 2,
	f : 0.345,
	g : "あ",
	h : "い"
};
 
■JSON 形式について
 
ECMAScript のリテラル表記に近い形で、文字列として表現したものが、JSON 形式です。
 
空白、タブ、改行などの整形用の文字は、自由に挿入する事ができます。
 

■JSON 形式で null 値を表現する

 
JSON では、null と記述すると、null 値を表現できます。
 
undefined 値を表現する事はできません。
 
null 値を JSON で表現する

null
 

■JSON 形式で数値を表現する

 
整数、小数、指数を表現できます。
 
「16 進数」や 「8 進数」の表記を使用する事はできません。
 
NaN 値や、Infinity 値を表現する事はできません。
 
整数値を JSON で表現する

123
 
小数値を JSON で表現する

-123.456
 
指数を JSON で表現する

1.2345e+4
 

■JSON 形式で文字列を表現する

 
文字列は、ダブルクォーテーション『" "』 でくくります。
 
シングルクォーテーション『' '』でくくる事はできません。
 
文字列を JSON で表現する

"あいうえお"
 
■エスケープ文字について
 
エスケープで表現できる文字は、以下の通りです。
 
表記Unicode説明
\bU+0008バックスペース
\fU+000Cフォームフィード
\nU+000Aラインフィード(改行コード)
\rU+000Dキャリッジ・リターン(改行コード)
\tU+0009水平タブ
\"U+0022ダブルクォーテーション
\/U+002Fスラッシュ
\\U+005Cバックスラッシュ(円記号)
 
エスケープを含めた文字列を JSON で表現する

"\tあいうえお\n\tかきくけこ"
 
■Unicodeスカラ値について
 
\uFFFF と記述すると、Unicode 1文字分を表現できます。
 
FFFF の部分には、ユニコードを 16 進数で表記します。
 
サロゲートペアとなるコードは、2つに分けて表記します。
 
例えば、U+10FFFF 文字は、\uD83F\uDFFF と表記します。
 
Unicodeスカラ値を含めた文字列を JSON で表現する

"\u3042 \u3044 \u3046 \u3048 \u304a"
 

■JSON 形式で配列を表現する

 
配列リテラルの書式を、そのまま利用できます。
 
配列を JSON で表現する

[ true , false , 0 , 1 , 2 , 0.345 , "あ" , "い" ]
 
多次元配列を JSON で表現する

[
	[
		["A","B","C"],
		["D","E","F"],
		["G","H","I"]
	],[
		["J","K","L","M"],
		["N","O","P","Q","R"]
	],[
		[
			["S","T","U"],
			["V","W"]
		],[
			["X"],
			["Y"],
			["Z"]
		]
	]
]
 

■JSON 形式でオブジェクトを表現する

 
オブジェクトのキーの部分は、文字列の表現と同じです。
 
必ずダブルクォーテーション『" "』 でくくる必要があります。
 
シングルクォーテーション『' '』でくくる事はできません。
 
また、クォーテーション表記を省略することもできません。
 
オブジェクトを JSON で表現

{ "a":true , "b":false , "c":0 , "d":1 , "e":2 , "f":0.345 , "g":"あ" , "h":"い" }
 
配列とオブジェクトの組み合わせを JSON で表現

{
	"aaa":{
		"count":123,
		"name":"テスト1",
		"result":false
	},
	"bbb":{
		"count":456,
		"name":"テスト2",
		"result":true
	},
	"ccc":{
		"count":789,
		"name":"テスト3",
		"param":{
			"ary":["a","b","c"],
			"name":"テスト4"
		},
		"result":true
	}
}
 


 

オブジェクトから JSON 文字列に変換する

 
 


■JSON.stringify() メソッドを使用する


「ActionScript のオブジェクト」から、「JSON 文字列」に変換するには、JSON.stringify() メソッドを使用します。
 
Flash Player 11 以降、AIR 3.0 以降で利用可能です。
 
JSON.stringify( オブジェクト , データ変換 , 整形 ) :String
第01引数 Objectオブジェクトや配列を指定。文字列、数値、真偽値、null でも可能。
第02引数(略可)*データ変換用コールバック関数を指定。もしくは、出力したいプロパティ名が格納された配列を指定。
第03引数(略可)*整形用文字列(空白、タブ、改行)を指定。もしくは、空白の個数を数値で指定。
戻り値 StringJSON 文字列が得られる。
 
「ActionScript のオブジェクト」から「JSON 文字列」に変換する

// ------------------------------------------------------------
// ActionScript のオブジェクトを用意する
// ------------------------------------------------------------
var obj:Object = {
	aaa:{
		count :123,
		name  :"テスト1",
		result:false
	},
	bbb:{
		count :456,
		name  :"テスト2",
		result:true
	},
	ccc:{
		count :789,
		name  :"テスト3",
		param :{
			ary :["a","b","c"],
			name:"テスト4"
		},
		result:true
	}
};

// ------------------------------------------------------------
// 「ActionScript のオブジェクト」から「JSON 文字列」に変換する
// ------------------------------------------------------------
var json_text:String = JSON.stringify(obj);

// テスト出力
trace(json_text);
 
■第02引数(コールバック関数を指定した場合)
 
データを変換するための、コールバック関数を指定する事ができます。
 
第01引数から、キー情報が得られます。(文字列型)
 
配列なら番地、オブジェクトならプロパティ名です。それ以外なら、空文字 "" が得られます。
 
第02引数から、本来の値情報が得られます。
 
戻り値から、新しい値情報を指定します。
 
undefined を返すと、プロパティを結果から除外する事ができます
 
入力データが、ネスト(入れ子)構造である場合、始祖から子孫へと順番に実行されます。
 
JSON.stringify() メソッドの第02引数に、変換用コールバック関数を指定する。

// ------------------------------------------------------------
// ActionScript のオブジェクトを用意する
// ------------------------------------------------------------
var obj:Object = {
	aaa:["A0","A1","A2"],
	bbb:{
		ccc:"C",
		ddd:"D",
		eee:{
			fff:"F",
			ggg:"G"
		}
	}
};


// ------------------------------------------------------------
// データ変換用コールバック関数
// ------------------------------------------------------------
function JsonStringifyReplacer(key:String,value:*):*{

	// 出力テスト
	trace("key:" + key + " value:" + value);

	// 変換したい値を返す(ここでは本来の値をそのまま返している)
	return value;
}

// ------------------------------------------------------------
// 「ActionScript のオブジェクト」から「JSON 文字列」に変換する
// ------------------------------------------------------------
var json_text:String = JSON.stringify(obj,JsonStringifyReplacer);

// テスト出力
trace(json_text);
 
■第02引数(配列を指定した場合)
 
任意のオブジェクトのプロパティを、結果に含めるかどうかを、配列形式で指定する事ができます。
 
オブジェクト型にのみ作用します。それ以外の型はすべて出力されます。
 
出力を許可したい場合、配列にプロパティ名を登録します。
 
JSON.stringify() メソッドの第02引数に、出力したいオブジェクトのプロパティ名を、配列形式で指定する。

// ------------------------------------------------------------
// ActionScript のオブジェクトを用意する
// ------------------------------------------------------------
var obj:Object = {
	aaa:["A0","A1","A2"],
	bbb:{
		ccc:"C",
		ddd:"D",
		eee:{
			fff:"F",
			ggg:"G"
		}
	}
};


// ------------------------------------------------------------
// 出力を許可したいプロパティを、配列に格納する
// ------------------------------------------------------------
var json_stringify_allow:Array = [
	"aaa",
	"bbb",
	"ddd"
];

// ------------------------------------------------------------
// 「ActionScript のオブジェクト」から「JSON 文字列」に変換する
// ------------------------------------------------------------
var json_text:String = JSON.stringify(obj,json_stringify_allow);

// テスト出力
trace(json_text);
 

■代替関数を使用する

 
「ActionScript のオブジェクト」から「JSON 文字列」に変換する関数です。
 
Flash 9 でも動作します。
 
ActionScript1.0 の場合は、こちら
 
「ActionScript のオブジェクト」から「JSON 文字列」に変換する関数

// ------------------------------------------------------------
// 「ActionScript のオブジェクト」から「JSON 文字列」に変換する関数
// ------------------------------------------------------------
function JsonStringify(obj:Object):String{
	var dic_e:Object = new Object();
	dic_e['\b'] = '\\b';
	dic_e['\f'] = '\\f';
	dic_e['\n'] = '\\n';
	dic_e['\r'] = '\\r';
	dic_e['\t'] = '\\t';
	dic_e['\"'] = '\\"';
	dic_e['\\'] = '\\\\';

	function stringify(obj:*):String{
		var r:Boolean;
		var i:Number;
		var num:Number;
		var k:String;
		var s:String;
		var type:String = typeof(obj);
		if(type == "object"){
			if(!obj){
				return "null";

			// 配列
			}else if(obj.constructor == Array){
				s = "[";
				num = obj.length;
				for(i=0;i < num;i++){
					if(i)	s += ",";
					s += stringify(obj[i]);
				}
				return s + "]";

			// オブジェクト
			}else{
				r = false;
				s = "{";
				for(k in obj){
					if(r)	s += ",";
					else	r = true;
					s += stringify(k) + ":" + stringify(obj[k]);
				}
				return s + "}";
			}

		// 文字列
		}else if(type == "string"){
			s = '"';
			num = obj.length;
			for(i=0;i < num;i++){
				if(dic_e[obj.charAt(i)] != undefined){
					s += dic_e[obj.charAt(i)];
				}else{
					s += obj.charAt(i);
				}
			}

			return s + '"';

		// 数値
		}else if(type == "number"){
			if(isNaN(obj)) return "null";
			if(obj == Number.POSITIVE_INFINITY) return "null";
			if(obj == Number.NEGATIVE_INFINITY) return "null";
			return obj.toString();

		}else if(type == "boolean"){
			return obj.toString();
		}else if(type == "null" || type == "undefined"){
			return "null";
		}
		return null;
	}

	return stringify(obj);
}
 
■使用例
 
「ActionScript のオブジェクト」から「JSON 文字列」に変換する

// ------------------------------------------------------------
// ActionScript のオブジェクトを用意する
// ------------------------------------------------------------
var obj:Object = {
	key_null  :[ null , undefined ],
	key_bool  :[ false , true ],
	key_number:[ 0 , -123 , 987.654 , Number.MIN_VALUE , Number.MAX_VALUE , Number.NaN , Number.POSITIVE_INFINITY , Number.NEGATIVE_INFINITY ],
	key_string:[ "あいうえお" , "/ \b \f \n \r \t \" \\" ],
	key_array :[ "a" , "b" , "c" ],
	key_object:{
		aaa:0,
		bbb:1,
		ccc:2
	}
};

// ------------------------------------------------------------
// 「ActionScript のオブジェクト」から「JSON 文字列」に変換する
// ------------------------------------------------------------
var json_text:String = JsonStringify(obj);

// 出力テスト
trace(json_text);
 


 

JSON 文字列からオブジェクトに変換する

 
 


■JSON.parse() メソッドを使用する

 
「JSON 文字列」から「ActionScript のオブジェクト」に変換するには、JSON.parse() メソッドを使用します。
 
Flash Player 11 以降、AIR 3.0 以降で利用可能です。
 
JSON.parse( "JSON 文字列" , コールバック関数 ) :Object
第01引数 StringJSON 文字列を指定。
第02引数(略可)Functionデータ変換用コールバック関数を指定。
戻り値 Objectオブジェクトや配列が得られる。もしくは、文字列、数値、真偽値、null が得られる。
 
JSON.stringify() メソッドの第02引数に、変換用コールバック関数を指定する。

// ------------------------------------------------------------
// JSON 文字列を用意する
// ------------------------------------------------------------
var json_text:String = '{"ary":[0,1,2],"obj":{"a":0,"b":1,"c":2}}';


// ------------------------------------------------------------
// 「JSON 文字列」から「ActionScript のオブジェクト」に変換する
// ------------------------------------------------------------
var obj:Object = JSON.parse(json_text);

// テスト出力
trace(obj);
 
■第02引数(コールバック関数)
 
データを変換するための、コールバック関数を指定する事ができます。
 
第01引数から、キー情報が得られます。(文字列型)
 
配列なら番地、オブジェクトならプロパティ名です。それ以外なら、空文字 "" が得られます。
 
第02引数から、本来の値情報が得られます。
 
戻り値から、新しい値情報を指定します。
 
undefined を返すと、プロパティを結果から除外する事ができます
 
入力データが、ネスト(入れ子)構造である場合、子孫から始祖へと順番に実行されます。
 
JSON.parse() メソッドの第02引数に、変換用コールバック関数を指定する。

// ------------------------------------------------------------
// JSON 文字列を用意する
// ------------------------------------------------------------
var json_text:String = '{"aaa":["A0","A1","A2"],"bbb":{"ddd":"D","eee":{"ggg":"G","fff":"F"},"ccc":"C"}}';


// ------------------------------------------------------------
// データ変換用コールバック関数
// ------------------------------------------------------------
function JsonParseReviver(key:String,value:*):*{

	// 出力テスト
	trace("key:" + key + " value:" + value);

	// 変換したい値を返す(ここでは本来の値をそのまま返している)
	return value;
}

// ------------------------------------------------------------
// 「JSON 文字列」から「ActionScript のオブジェクト」に変換する
// ------------------------------------------------------------
var obj:Object = JSON.parse(json_text,JsonParseReviver);

// テスト出力
trace(obj);
 

■代替関数を使用する

 
「JSON 文字列」を解析して「ActionScript のオブジェクト」に変換する関数です。
 
Flash 9 でも動作します。
 
ActionScript1.0 の場合は、こちら
 
「JSON 文字列」から「ActionScript のオブジェクト」に変換する関数

// ------------------------------------------------------------
// 「JSON 文字列」から「ActionScript のオブジェクト」に変換する関数
// ------------------------------------------------------------
function JsonParse(text:String):Object{
	var pre_w:Object = new Object();
	var pre_u:Object = new Object();
	var pre_b:Object = new Object();
	var pre_n:Object = new Object();
	var pre_s:Object = new Object();
	var pre_a:Object = new Object();
	var pre_o:Object = new Object();
	var dic_d:Object = new Object();
	var dic_e:Object = new Object();
	pre_u['n'] = pre_b['t'] = pre_b['f'] = pre_s['"'] = pre_a['['] = pre_o['{'] = pre_w[' '] = pre_w['\t'] = pre_w['\r'] = pre_w['\n'] = true;
	pre_n['0'] = pre_n['1'] = pre_n['2'] = pre_n['3'] = pre_n['4'] = pre_n['5'] = pre_n['6'] = pre_n['7'] = pre_n['8'] = pre_n['9'] = pre_n['-'] = true;
	dic_d['0'] = dic_d['1'] = dic_d['2'] = dic_d['3'] = dic_d['4'] = dic_d['5'] = dic_d['6'] = dic_d['7'] = dic_d['8'] = dic_d['9'] = true;
	dic_e['/'] = '/'; dic_e['b'] = '\b'; dic_e['f'] = '\f'; dic_e['n'] = '\n'; dic_e['r'] = '\r'; dic_e['t'] = '\t'; dic_e['\"'] = '\"'; dic_e['\\'] = '\\';

	var p:Number = 0;
	var num:Number = text.length;

	function skip():void{
		while(pre_w[text.charAt(p)]){
			p++;
			if(p >= num){
				return;
			}
		}
	}

	function parse():*{
		var r:Boolean;
		var c:String;
		var w:String;
		var s:Number;
		var e:Number;

		skip();
		c = text.charAt(p);

		// オブジェクト
		if(pre_o[c]){
			var obj:Object = new Object();

			p++;
			skip();
			r = true;
			while(true){
				c = text.charAt(p);
				if(c == '}'){
					if(!r) throw("JsonParse: Missing comma(,) position:" + p);
					p++;
					break;
				}
				if(c != '"') throw("JsonParse: Missing double quote(\") position:" + p);

				w = parse();

				skip();
				if(text.charAt(p) != ':') throw("JsonParse: Missing semicolon(:) position:" + p);
				p++;
				skip();

				obj[w] = parse();

				skip();
				if(p >= num){ throw("JsonParse: Missing curly bracket(}) position:" + p); }

				r = (text.charAt(p) != ',');
				if(!r){
					p++;
					skip();
				}
			}

			return obj;

		// 配列
		}else if(pre_a[c]){
			var ary:Array = new Array();

			p++;
			skip();
			r = true;
			while(true){
				if(text.charAt(p) == ']'){
					if(!r) throw("JsonParse: Missing comma(,) position:" + p);
					p++;
					break;
				}

				ary.push(parse());

				skip();
				if(p >= num){ throw("JsonParse: Missing square bracket(]) position:" + p); }

				r = (text.charAt(p) != ',');
				if(!r){
					p++;
					skip();
				}
			}

			return ary;

		// 文字列
		}else if(pre_s[c]){
			p++;

			var str:String = "";
			while(true){
				if(p >= num)  throw("JsonParse: Missing double quote(\") position:" + p);
				c = text.charAt(p);
				p++;
				if(c == '"'){
					break;
				}else if(c == "\\"){
					c = text.charAt(p);
					p++;
					if(c == 'u'){
						e = 0;
						r = ((num - p) > 4);
						if(r){
							s = text.charCodeAt(p);
							if(!s)			s = 0;
							if(s >= 97)		s -= 87;
							else if(s >= 65)	s -= 55;
							else			s -= 48;
							if(0 <= s && s < 16){
								e += s * 0x1000;
								p++;
							}else{
								r = false;
							}
						}
						if(r){
							s = text.charCodeAt(p);
							if(!s)			s = 0;
							if(s >= 97)		s -= 87;
							else if(s >= 65)	s -= 55;
							else			s -= 48;
							if(0 <= s && s < 16){
								e += s * 0x0100;
								p++;
							}else{
								r = false;
							}
						}
						if(r){
							s = text.charCodeAt(p);
							if(!s)			s = 0;
							if(s >= 97)		s -= 87;
							else if(s >= 65)	s -= 55;
							else			s -= 48;
							if(0 <= s && s < 16){
								e += s * 0x0010;
								p++;
							}else{
								r = false;
							}
						}
						if(r){
							s = text.charCodeAt(p);
							if(!s)			s = 0;
							if(s >= 97)		s -= 87;
							else if(s >= 65)	s -= 55;
							else			s -= 48;
							if(0 <= s && s < 16){
								e += s * 0x0001;
								p++;
							}else{
								r = false;
							}
						}
						if(r){
							str += String.fromCharCode(e);
						}else{
							throw("JsonParse: Invalid codepoint. position:" + p);
						}
					}else if(dic_e[c] != undefined){
						str += dic_e[c];
					}else{
						throw("JsonParse: Invalid escape. position:" + (p-1));
					}
				}else{
					str += c;
				}
			}
			return str;

		// 数値
		}else if(pre_n[c]){
			s = p;
			p ++;

			while(dic_d[text.charAt(p)]){
				p++;
			}

			r = false;
			if(text.charAt(p) == '.'){
				p++;
				r = true;

				if(!dic_d[text.charAt(p)]){
					throw("JsonParse: Missing digits after decimal. position:" + p);
				}
				p++;

				while(dic_d[text.charAt(p)]){
					p++;
				}
			}
			if(text.charAt(p) == 'e'){
				p++;
				r = true;

				c = text.charAt(p);
				if(c == '+' || c == '-'){
					p++;
				}

				if(!dic_d[text.charAt(p)]){
					throw("JsonParse: Missing digits after exponent. position:" + p);
				}
				p++;

				while(dic_d[text.charAt(p)]){
					p++;
				}
			}

			if(r)	return parseFloat(text.substring(s,p));
			else	return parseInt(text.substring(s,p));

		// 真偽値
		}else if(pre_b[c]){
			w = text.substr(p, 5);
			if(w == "false"){
				p += 5;
				return false;
			}
			if(w.indexOf("true") == 0){
				p += 4;
				return true;
			}

		// null 値
		}else if(pre_u[c]){
			if(text.substr(p, 4) == "null"){
				p += 4;
				return null;
			}
		}

		throw("JsonParse: Unable to parse value. position:" + p);
	}

	var data:* = parse();
	skip();
	if(p < num) throw("JsonParse: Unexpected character after JSON. position:" + p);
	return data;
}
 
■使用例
 
「JSON 文字列」から「ActionScript のオブジェクト」に変換する

// ------------------------------------------------------------
// JSON 文字列を用意する
// ------------------------------------------------------------
var json_text:String = '{"key_null":null,"key_bool":[false,true],"key_number":[0,-123,987.654,5e-324,1.7976931348623157e+308],"key_string":["あいうえお","\\/ \\b \\f \\n \\r \\t \\" \\\\"],"key_array":["a","b","c"],"key_object":{"aaa":0,"bbb":1,"ccc":2}}';

// ------------------------------------------------------------
// 「JSON 文字列」から「ActionScript のオブジェクト」に変換する
// ------------------------------------------------------------
var obj:Object = JsonParse(json_text);

// 出力テスト
trace(obj);