uhyohyo.net

JavaScript初級者から中級者になろう

六章第一回 XML・XHTMLとは

六章では、DOMにおけるXMLとXHTMLの扱いについて解説していきます。そこで、まずXML・XHTMLとは何かということを解説していきます。

XML

Extensible Markup Language(XML)は、HTMLと同じようにタグを使ってさまざまなデータを表すことができる仕組みです。

さまざまなデータとは、本当になんでもいいのです。XMLによってつくられたデータは、さまざまなことに利用されます。例えば、プログラムがデータを保存するのに使ったりされます。

HTMLと比べて最大の特徴は、自分で仕様を決められるという点です。つまり、自分でタグ名あるいは属性名などを決められるということです。具体的なXML文書の例を示します。

<?xml version="1.0" ?>
<users>
  <ユーザー>
    <名前>Aさん</名前>
    <年齢>23</年齢>
  </ユーザー>
  <ユーザー>
    <名前>Bさん</名前>
    <年齢>100</年齢>
  </ユーザー>
</users>
        

まず一見して違和感を覚えるのは、タグ名が日本語であるものがあるということですね。前述のようにXMLではタグ名も自由に決めることができるので、このように日本語も可能です。とはいっても、やはり普通に半角英数字で書くということのほうが多いと思います。そのほうが国際的ですしね。

最初の行の<?xml version="1.0" ?>は、XMLでは書くことになっているもので、この文書がXMLであることを表すものです。XML文書には、これが必要です。

次に、この文書全体は<users> 〜 </users>で囲われています。このような要素をルート要素などといいます。HTMLでもルート要素はありましたね。全体が<html> 〜 </html>で囲まれているから、html要素がルート要素だといえますね。

そして、そのなかには<ユーザー> 〜 </ユーザー>の組が2つあります。実は今回例としたこの文書は、ユーザーの一覧を例にしたものでした。

ここで、XMLでデータをつくることの利点が出てきています。このような、階層構造(木構造)を簡単に表現できるという点です。

今回の場合、

users
|
├――ユーザー
|    |
|    ├――名前
|    |
|    └――年齢
|
└――ユーザー
     |
     ├――名前
     |
     └――年齢
          

という木構造になっていて、usersがユーザーのリストで、それぞれのユーザーは名前と年齢というデータを持っているということは簡単に分かります。

人間が見た目にも分かりやすいというのも利点のひとつかもしれません。

ここで、「users」「ユーザー」「名前」「年齢」というタグ名は誰が決めたのでしょうか。今回に限って言えば筆者たる自分ですが、一般にそのプログラムで使うデータを作る場合、そのプログラムを作った人が、そのXMLをどんな構造にするか、どんなタグ名を使うかということも決めます。有名になったりすると、複数のプログラムで共通の書き方が使われるかもしれません。広く普及してスタンダードになったものもたくさんあります。そうなると、別の名前が付けられたりします。例えばSVGという画像フォーマットがありますが、その中身はただのXMLファイルです。XMLでこう書いたらこういう画像になる、というルールが決められてそれが標準となったので、いまSVGとして広く知られています。

また、どのような構造にするかも決めます。今回の場合ルート要素がusersで、usersの子はいくつかのユーザー要素で、それぞれのユーザー要素は名前と年齢を持つ、ということになります。

構造がしっかりと決まっていれば、プログラムからそれを読み込むのも容易です。

また、XMLでは、複雑なデータを表すことができます。複雑なデータでも分かりやすく書くことができるのですが、複雑でも読み込むのが容易だというのがよく使われる理由だといえます。というのも、前にDOMはHTMLだけでなくXMLも扱うことができるということを解説しました。複雑なXMLも、DOMを使えば読み込むのは簡単なのです(DOM以外にもXMLを扱う手段は一応あります)。

また、DOMが使えるのは、JavaScriptだけではありません。Javaだったり、あるいはPHPなどでもDOMを使うことができるそうです。他にもあると思います。

DOMでXMLを扱う

DOMでは、HTMLだけでなくXMLも扱えます。つまり、こんな感じです。

var xmlDocument;	//このxmlDocumentはHTMLでいうところのdocumentにあたるもので、XML文書全体を表します。ここでは上のサンプルの文書の場合を想定します。

var users = xmlDocument.documentElement;	//documentElementはルート要素だから、今回の場合users要素のノードになります。このノードというのも、HTMLを扱うときのノードと同じ概念です。
users.getElementsByTagName('ユーザー');		//usersが持つユーザー要素のリストを返します。2つのユーザー要素がありますね。
          

xmlDocumentを実際に取得する方法をここでは書いていないため、実際に実行できるサンプルではないので理解しにくいかもしれませんが、こんな感じでXMLも扱えます。

実際に存在するXMLを読み込んで処理したりすることももちろんできますが、それはまたそのうち解説します。

XHTML

また、XHTMLというものがあります。もともとHTMLはXMLとは似ていても少し違うものでしたが、そこで、HTMLをXML文書の一種として書けるようにしたものを作りました。それがXHTMLです。したがって、XHTMLは、XMLとしても通用するということになります。

HTMLとの相違点

基本はHTMLと同じですが、XMLの厳密な仕様に対応させるために、多少の相違点が生まれます。

例えば、要素名や属性名は小文字にするということです。HTMLでは<HTML> 〜 </HTML><html> 〜 </html>は同じものとして扱われましたが、そういうわけにはいかなくなります。

というのも、そもそもXMLが大文字と小文字を区別するからこのようなことになっています。「HTML」と「html」を違うものとして扱うXMLにあわせるためには、「大文字と小文字どちらでもOK」というわけにはいかなくなったのです。

そこで、XHTMLでは全て小文字に統一されました。厳密にXHTMLを解釈した場合、タグ名が大文字の場合、「こんなタグ知らない」といわれて正しく表示されないということになります。

また、もうひとつ大きな違いがあります。それは、終了タグが絶対に必要だということです。

HTMLでは、終了タグは省略可能なものがあり、例えばli要素の終了タグは

<ul>
  <li>あああ</li>
  <li>いいい</li>
  <li>ううう</li>
</ul>

というリストがあった場合、

<ul>
  <li>あああ
  <li>いいい
  <li>ううう
</ul>

のように省略ができました。しかし、XHTMLではこれらの省略は認められません。そもそもXMLに終了タグの省略という仕様がないからです。

そもそもXMLはいろいろなデータに利用できる汎用的な仕様だから、あらかじめタグ名によってこのタグは省略可能だとかそういうことは決められませんね。

また、これは、もともと終了タグがないタグも例外ではありません。

例えば、HTMLでは終了タグがない

<img src="aaa.gif" alt="aaa">

のようなものにも終了タグが必要です。どうすればいいかというと、imgは「中身がない要素」として扱い、

<img src="aaa.gif" alt="aaa"></img>

のように開始タグの直後に終了タグを置きます。

ただ、このように中身が何もない場合、次のような省略記法が許されています。

<img src="aaa.gif" alt="aaa" />

開始タグと終了タグがひとつになり、もともとのHTMLの書き方に近くなりました。これはどんなタグでも同じです。<br />のような書き方は目にしたことがあるのではないでしょうか。

ついでに、style要素やscript要素を書くときにも注意が必要です。具体的には、style要素やscript要素の中身を次のようにしないといけません。

<script type="text/javascript"><![CDATA[
  var aaa = 123;
  console.log(aaa*2);
]]></script>
        

script要素の中身の全体が<![CDATA[ 〜 ]]>で囲まれています。これで囲んだ部分はCDATAセクションといって、style要素やscript要素の中身は普通これにします(絶対というわけではありませんが)。

一応、これら以外でもCDATAセクションは使えます。これの意味ですが、CDATAセクションの中では特別な意味を持つ文字も記述できることになっています。つまり、< >などはタグを記述するのに使われる記号だから、普通&lt; &gt;のように書く必要がありますが、CDATAセクションの中ではこれらはそのまま書くことが出来ます。だから、

<script type="text/javascript"><![CDATA[
  var a = 10;
  if(a < 5){
    }else if(a > 15){
  }
]]></script>

のように書くことが出来ます。ただし、例外として、 ]]> だけは直接書けません。CDATAセクションの終わりだと解釈されてしまうからですね。

ちなみに、逆に言うと、CDATAセクションを使わない場合

<script type="text/javascript">
var a = 10;
if(a &lt; 5){
    }else if(a &gt; 15){
}
</script>
          

のように書かないといけないということです。なぜなら、<などをそのまま書いた場合、それがタグの始まりと解釈されてしまい文法エラーになるからです。これもHTMLとは違う点ですね。HTMLでは一応、そのまま書くことが出来ました(これも実はscript要素の特例的な処理の賜物です。いちいちscript要素中で&lt;などと書くのは面倒くさいですよね)。