“JSON” – Alphabetical Advent Calendar 2013
この記事は賞味期限切れです。(更新から1年が経過しています)
“J” は JSON の “J”。
JSON
JSON は “JavaScript Object Notation” の略称で、 今や息をするように当たり前のように使われているデータフォーマットです。
- サイズが少なくて済む
- 書式に馴染みがある(JavaScriptのオブジェクトリテラルほぼそのまま)
- データの型をそのまま活かせる
などの特徴を持ち、Webアプリケーションのデータのやり取りだけでなく、 node.js のパッケージ定義ファイル(package.json)や、 Sublime Text 2 等ソフトウェアの設定ファイル等、様々な場面で目にするようになりました。
生成・パース
JSON文字列の生成・展開は JSON オブジェクトの stringify / parse メソッドを通して行うことが出来ます。
var person = {
name: "john",
age: 15,
active: true,
tags: ["JavaScript", "CSS", "HTML"]
};
var json = JSON.stringify(person);
// '{"name":"john","age":15,"active":true,"tags":["JavaScript","CSS","HTML"]}'
var parsed = JSON.parse(json);
// { name: "john", ... }
JSON APIは古いブラウザ等では使えない場合もありますが、 その場合は json2.js などを利用する事で、 レガシーな環境でも JSON.parse/stringify を使用出来るようになります。 あるいは、パースするだけならば jQuery に $.parseJSON メソッドが用意されています。
$.parseJSON('{"name":"john","age":15,"active":true,"tags":["JavaScript","CSS","HTML"]}');
型 と toJSON メソッド
型を活かせるとは言っても全てがそうなのではなく、JSONで表現できる型は限られています。 JSONはあくまでJSONであって、JavaScriptではないという事ですね。
表現できる型は以下となります。
- 数値
- 文字列
- 真偽値
- 配列
- オブジェクト(連想配列)
- null
それ以外の型については、Date オブジェクトのように toJSON メソッドを持つ物であればその結果が代入されます。 (Date.toJSON は ISO文字列を返します) ただし、パース時に元のオブジェクトに変換してくれたりはしません。
var data = {
date: new Date()
};
JSON.stringify(date); // {"date":"2013-11-11T03:46:11.583Z"}
つまり、toJSON メソッドを定義してさえ置けば、そのままJSONに渡せてしまうという事です。 backbone.js の Model や Collection には toJSON メソッドが実装されており、そのままスムーズにデータのやり取りをする事が出来ます。 自前のクラス等をつくる際には toJSON を生やしておくと色々捗りそうです。
JSONPath
全く違う話になりますが、XMLのデータの必要な情報にだけアクセスする XPath という物があります。 XML文書あるいはそのデータから “//chapter[@title=”第1章”]/paragraph” のような文字列表現で条件を指定することで、 条件に適合するデータを抽出するという物なのですが、 JSON にも同じ趣向のライブラリがあります。それが JSONPath です。
http://goessner.net/articles/JsonPath
JSONPath is a lightweight component that allows to find and extract relevant portions out of JSON structures on the client as well as on the server.
JavaScriptの実装は、90行程度に収まっています。 簡単な例で試してみましょう。
var data = {
length: 3,
items: [
{
name: "JavaScript 第6版",
price: 4410,
author: "David Flanagan"
},
{
name: "JavaScript: The Good Parts",
price: 1890,
author: "Douglas Crockford"
},
{
name: "JavaScriptパターン",
price: 2940,
author: "Stoyan Stefanov"
}
]
};
// price が2000超の本の著者を抽出する
var authors = jsonPath(data, "$.items[?(@.price>2000)].author");
// ["David Flanagan", "Stoyan Stefanov"]
“$” がルートを示し、そこから “.” で下層を辿っていき、”?” を使って属性でフィルタをかけたりする事ができます。 “@” は自身のノードを指します。 詳しい書式については 参考ページ にXPathとの対応表として掲載されています。
慣れないと時間がかかりそうですが、大きなデータからの抽出に役立つかもしれません。
コメント