E4Xチュートリアル(w3schools.comとMDC)を読んだので内容を簡単に列挙してみる
※このエントリは元ネタのサイトの内容を忠実に翻訳する目的ではなく、自分の理解をまとめる目的で書いています。内容に誤りがある可能性があります。誤り等についてご指摘頂ければうれしいです。
元ネタ:
E4X Tutorial
ちなみに以下のコードの確認はFirebugのコンソールや、Vimperatorのコマンドラインを使えば動作が確認できる。
自分はVimperatorのコマンドラインを使って確認した。たぶんこれが一番お手軽。
E4Xとは?
ECMAScript(Javascriptの正式な名前)for XML の略称。
実際には"Javascript for XML"とも言える。
DateオブジェクトやArrayオブジェクトのように組み込みのXMLオブジェクトを持つ
var x = new XML() var y = new Date() var z = new Array()
E4XによってJavascript内でXMLを簡単に扱うことが可能になる。
E4XはWeb標準仕様。以下から仕様を参照できる。
Standard ECMA-357
どうやって使うのか?
XMLの書式に従って記述された文字列から生成する方法
var text = "<hoge><date>2009-02-14</date><name>Taro</name></hoge>"; var xml = new XML(text);
直接XMLを記述する方法
var x = new XML(); x = <hoge> <date>2009-02-14</date> <name>Taro</name> </hoge>;
ドット演算子で要素を参照(上記の例の'x'を使う場合...)
document.write(x.name);
という感じで普通のオブジェクトのプロパティのようにノードを参照することができる。
[]でも参照できる
document.write(x["name"]);
なんでE4Xなのか?
E4Xで書くとシンプルに書ける*1から。
E4Xが無い場合(Firefox等) *2
var xmlDoc = document.implementation.createDocument("","",null);
xmlDoc.load('hoge.xml');
xmlDoc.onload = function() {
document.write(this.getElementsByTagName("name")[0].firstChild.nodeValue);
}; E4Xがあると
var xmlDoc = new XML();
xmlDoc.load('hoge.xml');
document.write(xmlDoc.name);
例題
以下のようなXMLを想定する。(個人の蔵書管理をイメージ)
<library>
<book isbn="123456789012">
<author email="hoge@example.com">hoge</author>
<publisher webpage="http://hoge.example.com/">Hoge inc.</publisher>
<price cur="doller">200</price>
<status>unread</status>
</book>
</library>例えば金額をドルから円に換算するとかは
var price_yen = library.book.price * rate;
という感じのコードで書ける(rateは適当な換算レートを入れる)
要素を追加する場合は以下のような感じで "+="演算子が使える
library.book +=
<book isbn="9999999999999">
<author email="fuga@example.com">fuga</author>
<publisher webpage="http://xxxxxxx.com">xxxxx</publisher>
<price cur="yen">3000</price>
<status>wish</status>
</book>属性を参照する
例えば著者のemailアドレスは
library.book.author.@email
で参照できる。
ループをまわす
var price = 0;
for each (i in library.book) {
price += i.price;
}こんな感じ
さらに..
※以下はMDCのサイトから抜粋、なのでもし書かしたらFirefox限定のものも含まれているかも。
元ネタ:
Introduction - MDC
普通のDOMのInterfaceも使える
var ele = <hoge/>; ele.appenChild(<fuga/>); // => <hoge><fuga/></hoge>
ブレース{}を使うと変数に置き換えることができる
var hoge = "Yatta!";
var fuga = <say>{hoge}</say>;
// => <say>Yatta!</say>属性でも使える
var email = "hoge@example.com";
var fuga = <author email={email}>hoge</author>;
// => <author email="hoge@example.com">hoge</author>
ブレースにより置き換えの注意
内部的にtoString()を呼び出しているので、オブジェクトを渡すと[object Object]という文字列に変換されてしまう。
たとえば
var x = {hoge: "fuga"};
var y = <foo>{x}</foo>;
// => <foo>[object Object]</foo>.toXMLString()又は.toString()でシリアライズ
まだ存在しない要素(プロパティ)に値を代入すると該当要素が新たに作られる。
var xml = <hoge/>; xml.fuga = 1; // => <hoge><fuga>1</fuga></hoge>
繰り返しの要素は配列のように扱える
var xml = <hoge>
<fuga>aaa</fuga>
<fuga>bbb</fuga>
</hoge>;
var fuga = xml.fuga;
// fuga[0] => "aaa"
// fuga[1] => "bbb"text()メソッドでテキストノードを配列で取り出せる
var xml = <hoge>Koreha <fuga>E4X NO</fuga> sample desu.</hoge>; xml.text(); // => ["Koreha ", " sample desu."]
comments()でコメント要素も取得できる
*セレクタを使うと子要素の配列を取得できる。(先の例とちがって異なる要素でもいい)
var hoge = <hoge>
<fuga/>
<foo/>
<bar/>
</hoge>
var x = hoge.*;
// x[0] = <fuga/>
// x[1] = <foo/>
// x[2] = <bar/>..(ドット2つ)で子孫要素を示すことができる。XPathの'//'みたいなもの。
ファイルシステムのように親を指すわけではない(まぎらわしい)ので注意。
var hoge = <hoge>
<moge>
<fuga>100</fuga>
<piyo>200</piyo>
</moge>
</hoge>
hoge..fuga
// => 100
hoge..piyo
// => 200*.(@hoge == "fuga")という感じでセレクタを書くと、要素をフィルタすることができる。