aboutsummaryrefslogtreecommitdiff
path: root/files/ja/orphaned/e4x/processing_xml_with_e4x/index.html
blob: d7421ddacf2771576f8227a178a2b33b98e0d428 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
---
title: E4X を用いた XML 処理
slug: orphaned/E4X/Processing_XML_with_E4X
tags:
  - E4X
  - JavaScript
  - NeedsTechnicalReview
  - XML
original_slug: E4X/Processing_XML_with_E4X
---
<div><div class="warning warningHeader">
    <p><strong>警告:</strong> E4X は非推奨です。E4X は content に対して Firefox 16 からデフォルトで無効に、chrome に対して Firefox 17 からデフォルトで無効に、そして Firefox 18 で削除される予定です。代替として、DOMParser/DOMSerializer または 非ネイティブの JXON アルゴリズムを使用してください。</p>
</div></div>

<div><div class="warning warningHeader">
    <p><strong>警告:</strong> <strong>この記事の内容は古くなっている可能性があります。</strong> 最終更新日は 2010 年 11 月 12 日です。英語版の最新の内容も合わせてご覧下さい。</p>
</div></div>

<p>JavaScript 1.6 で初めて導入された <strong><a href="/ja/E4X" title="ja/E4X">E4X</a></strong> により、JavaScript 言語にネイティブ XML オブジェクトが導入され、さらに XML 文書リテラルを JavaScript コードに埋め込むための構文も追加されています。</p>

<p>E4X の完全な定義は <a class="external" href="http://www.ecma-international.org/publications/standards/Ecma-357.htm">Ecma-357 仕様</a> でなされています。この章では実用的な概要を示します。完全なリファレンスではありません。</p>

<p><span id="Compatibility_issues"></span></p>

<h2 id="互換性の問題">互換性の問題</h2>

<p><code>&lt;script&gt;</code> 要素のサポートがブラウザの間で広く普及する前は、JavaScript をページに埋め込むときに HTML コメントタグで囲むことで、<code>&lt;script&gt;</code> を知らないブラウザが JavaScript コードをそのまま表示してしまうのを防ぐということが一般的でした。この慣習はもう不要ですが、古いコードでは残っていることがあります。後方互換性のため、E4X はコメントや CDATA セクションを無視するのがデフォルトの動作です。<code>e4x=1</code> 引数を <code>&lt;script&gt;</code> タグに加えることでこの制限を無効にできます。</p>

<pre>&lt;script type="text/javascript;e4x=1"&gt;
...
&lt;/script&gt;
</pre>

<p><span id="Creating_an_XML_object"></span></p>

<h2 id="XML_オブジェクトの作成">XML オブジェクトの作成</h2>

<p>E4X には XML オブジェクトを作成する方法が 2 つあります。1 つ目は <code>XML</code> コンストラクタに文字列を渡す方法です。</p>

<pre class="eval"> var languages = new XML('&lt;languages type="dynamic"&gt;&lt;lang&gt;JavaScript&lt;/lang&gt;&lt;lang&gt;Python&lt;/lang&gt;&lt;/languages&gt;');
</pre>

<p>2 つ目はスクリプトに XML を XML リテラルとして直接埋め込むことです。</p>

<pre class="eval"> var languages = &lt;languages type="dynamic"&gt;
   &lt;lang&gt;JavaScript&lt;/lang&gt;
   &lt;lang&gt;Python&lt;/lang&gt;
 &lt;/languages&gt;;
</pre>

<p>どちらの場合も結果として得られるオブジェクトは E4X XML オブジェクトです。これには内部データにアクセスしたりそれを変更したりするための便利な構文が備わっています。</p>

<p>XML オブジェクトは通常の JavaScript オブジェクトのように見え、そのような挙動をとりますが、その 2 つは同じものではありません。E4X では E4X XML オブジェクトにおいてのみ動作する新たな構文が導入されています。その構文は JavaScript プログラマにとって取っつきやすいように設計されていますが、E4X では XML からネイティブ JavaScript オブジェクトへの直接のマッピングが用意されていません。そう見えるだけです。</p>

<p><span id="Working_with_attributes"></span></p>

<h2 id="属性の操作">属性の操作</h2>

<p>上記の例を実行すると変数 languages は XML 文書の <code>&lt;languages&gt;</code> に対応する XML オブジェクトへの参照となります。このノードには type という 1 つの属性があり、それにアクセスしたり、それを変更したりする方法はいくつもあります。</p>

<pre class="eval"> alert(languages.@type); // "dynamic" というアラート
 languages.@type = "agile";
 alert(languages.@type); // "agile" というアラート
</pre>

<pre class="eval"> alert(languages.toString());
 /* アラート:
   &lt;languages type="agile"&gt;&lt;lang&gt;JavaScript&lt;/lang&gt;&lt;lang&gt;Python&lt;/lang&gt;&lt;/languages&gt;
 */
</pre>

<p><span id="Working_with_XML_objects"></span></p>

<h2 id="XML_オブジェクトの操作">XML オブジェクトの操作</h2>

<p>XML オブジェクトにはその中身を検査したり変更するためのメソッドがたくさん用意されています。それらは JavaScript の通常のドットや <code>[]</code> という記法をサポートしていますが、オブジェクトのプロパティにアクセスするのではなく、E4X ではその要素の子にアクセスするための演算子として定義されています。</p>

<pre>var person = &lt;person&gt;
  &lt;name&gt;Bob Smith&lt;/name&gt;
  &lt;likes&gt;
    &lt;os&gt;Linux&lt;/os&gt;
    &lt;browser&gt;Firefox&lt;/browser&gt;
    &lt;language&gt;JavaScript&lt;/language&gt;
    &lt;language&gt;Python&lt;/language&gt;
  &lt;/likes&gt;
&lt;/person&gt;;

alert(person.name); // Bob Smith
alert(person['name']); // Bob Smith
alert(person.likes.browser); // Firefox
alert(person['likes'].browser); // Firefox
</pre>

<p>複数の要素がマッチするようなものにアクセスすると <code>XMLList</code> が返されます。</p>

<pre>alert(person.likes.language.length()); // 2
</pre>

<p>DOM と同様に <code>*</code> を使うことですべての子ノードにアクセスすることができます。</p>

<pre>alert(person.likes.*.length()); // 4
</pre>

<p><code>.</code> 演算子は与えられたノードの直接の子にアクセスしますが、<code>..</code> 演算子はネストの深さにかかわらずすべての子にアクセスします。</p>

<pre>alert(person..*.length()); // 11
</pre>

<p>この場合、<code>length()</code> メソッドは 11 を返します。結果として得られる <code>XMLList</code> には要素とテキストノードがともに含まれるためです。</p>

<p>XML 要素を表すオブジェクトには便利なメソッドがたくさん用意されています。そのうちのいくつかを以下に示します。 <span class="comment">TODO: Add all of the methods to the JavaScript reference, link from here</span></p>

<pre>alert(person.name.text()) // Bob Smith

var xml = person.toXMLString(); // XML からなる文字列

var personCopy = person.copy(); // XML オブジェクトのディープコピー

var child = person.child(1); // 2 番目の子ノード:この場合は &lt;likes&gt; 要素
</pre>

<p><span id="Working_with_XMLLists"></span></p>

<h2 id="XMLLists_の操作">XMLLists の操作</h2>

<p>XML オブジェクトに加えて、E4X では <code>XMLList</code> オブジェクトが導入されています。<code>XMLList</code> は XML オブジェクトの順序付きの集まりを表します。例えば、要素のリストです。上記の例に続き、次のようにすると <code>&lt;lang&gt;</code> 要素の <code>XMLList</code> にアクセスすることができます。</p>

<pre class="eval"> var langs = languages.lang;
</pre>

<p><code>XMLList</code> には格納している要素数を知るための <code>length()</code> メソッドがあります。</p>

<pre class="eval"> alert(languages.lang.length());
</pre>

<p>JavaScript の配列とは違い、length はプロパティではなくメソッドであり、必ず <code>length()</code> として呼び出さなければならないことに注意してください。</p>

<p>次のようにしてマッチする要素について繰り返すことができます。</p>

<pre class="eval"> for (var i = 0; i &lt; languages.lang.length(); i++) {
     alert(languages.lang[i].toString());
 }
</pre>

<p>ここでは配列のアイテムに順にアクセスするときと全く同じ構文を使っています。このように通常の配列に似ているにもかかわらず、<code>XMLList</code><code>forEach</code> のような <code>Array</code> のメソッドをサポートしていません。また、<code>Array.forEach()</code> のような Array のジェネリックスも <code>XMLList</code> オブジェクトとは互換性がありません。</p>

<p>JavaScript 1.6 で JavaScript の E4X サポートの一部として導入された <a href="/ja/JavaScript/Reference/Statements/for_each...in" title="ja/JavaScript/Reference/Statements/for_each...in">for each...in 文</a> を使うこともできます。</p>

<pre class="eval"> for each (var lang in languages.lang) {
     alert(lang);
 }
</pre>

<p><code>for each...in</code> は通常の JavaScript のオブジェクトについて使うと、そのオブジェクトに含まれる値(キーではなく)に対して繰り返すこともできます。<a href="/ja/JavaScript/Reference/Statements/for...in" title="ja/JavaScript/Reference/Statements/for...in">for...in</a> と同様、配列について使用するのは <a href="/ja/JavaScript/Reference/Statements/for...in#.E8.AA.AC.E6.98.8E" title="ja/JavaScript/Reference/Statements/for...in#.E8.AA.AC.E6.98.8E">全く推奨できません</a></p>

<p>整形式の XML を文書を作らずとも、次のような XML リテラル構文を用いて <code>XMLList</code> を作ることができます。</p>

<pre class="eval"> var xmllist = &lt;&gt;
   &lt;lang&gt;JavaScript&lt;/lang&gt;
   &lt;lang&gt;Python&lt;/lang&gt;
 &lt;/&gt;;
</pre>

<p><code>+=</code> 演算子を使うと文書内の <code>XMLList</code> に要素を新たに追加することができます。</p>

<pre class="eval"> languages.lang += &lt;lang&gt;Ruby&lt;/lang&gt;;
</pre>

<p>通常の DOM メソッドで返されるノードリストとは異なり、<code>XMLList</code> は静的であり、DOM 内の変更が自動的には反映されません。既存の <code>XML</code> オブジェクトのサブセットとして <code>XMLList</code> を作成し、その後オリジナルの <code>XML</code> を変更した場合、<code>XMLList</code> にはその変更が反映されません。最新の状態にするには作り直す必要があります。</p>

<pre class="eval"> var languages = &lt;languages&gt;
   &lt;lang&gt;JavaScript&lt;/lang&gt;
   &lt;lang&gt;Python&lt;/lang&gt;
 &lt;/languages&gt;;

 var lang = languages.lang;
 alert(lang.length()); // 2 というアラート

 languages.lang += &lt;lang&gt;Ruby&lt;/lang&gt;;
 alert(lang.length()); // やはり 2 というアラート

 lang = languages.lang; // XMLList を作り直す
 alert(lang.length()); // 3 というアラート
</pre>

<p><span id="Searching_and_filtering"></span></p>

<h2 id="検索とフィルタ">検索とフィルタ</h2>

<p>E4X には特定の基準にマッチする文書内のノードを選択するための特別な演算子が用意されています。このようなフィルタ演算は丸括弧で囲んだ式で指定します。</p>

<pre>var html = &lt;html&gt;
  &lt;p id="p1"&gt;First paragraph&lt;/p&gt;
  &lt;p id="p2"&gt;Second paragraph&lt;/p&gt;
&lt;/html&gt;;

alert(html.p.(@id == "p1")); // "First paragraph" というアラート
</pre>

<p>式の手前のパスにマッチするノード(この場合は p 要素)は式が評価される前にスコープチェーンに追加されます。<a href="/ja/JavaScript/Reference/Statements/with" title="ja/JavaScript/Reference/Statements/with">with 文</a> を使ってノードが指定されているかのような動作です。</p>

<p>したがって、フィルタは現在の要素内の単一ノードの値に対しても実行することができます。</p>

<pre>var people = &lt;people&gt;
  &lt;person&gt;
    &lt;name&gt;Bob&lt;/name&gt;
    &lt;age&gt;32&lt;/age&gt;
  &lt;/person&gt;
  &lt;person&gt;
    &lt;name&gt;Joe&lt;/name&gt;
    &lt;age&gt;46&lt;/age&gt;
  &lt;/person&gt;
&lt;/people&gt;;

alert(people.person.(name == "Joe").age); // 46 というアラート
</pre>

<p>フィルタ式に JavaScript 関数を使うこともできます。</p>

<pre>function over40(i) {
    return i &gt; 40;
}

alert(people.person.(over40(parseInt(age))).name); // Joe というアラート
</pre>

<p><span id="Handling_namespaces"></span></p>

<h2 id="名前空間の処理">名前空間の処理</h2>

<p>E4X は名前空間を考慮しています。ノードや属性を表すあらゆる XML オブジェクトには <code>QName</code> オブジェクトを返す <code>name()</code> メソッドがあり、名前空間要素を簡単に検査することができます。</p>

<pre>var xhtml = &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
	&lt;head&gt;
		&lt;title&gt;Embedded SVG demo&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;h1&gt;Embedded SVG demo&lt;/h1&gt;
		&lt;svg xmlns="http://www.w3.org/2000/svg"
			viewBox="0 0 100 100"&gt;
			&lt;circle cx="50"
				cy="50"
				r="20"
				stroke="orange"
				stroke-width="2px"
				fill="yellow" /&gt;
		&lt;/svg&gt;
	&lt;/body&gt;
&lt;/html&gt;;

alert(xhtml.name().localName); // "html" というアラート
alert(xhtml.name().uri); // "http://www.w3.org/1999/xhtml" というアラート
</pre>

<p>名前空間内にある要素にアクセスするには、まずその名前空間についての URI を格納した <code>Namespace</code> オブジェクトを作ります。</p>

<pre>var svgns = new Namespace('http://www.w3.org/2000/svg');
</pre>

<p>すると、通常の要素指定子の代わりに <code>namespace::localName</code> の形式で E4X クエリに使用することができます。</p>

<pre>var svg = xhtml..svgns::svg;
alert(svg); // 文書の &lt;svg&gt; 部分が表示される
</pre>

<p></p>